使用 python DataFrame 附加 google 工作表
Appending google sheets with python DataFrame
我尝试用 python df 附加 google sheet。
google sheet 授权后,我试了这个:
sheet = service.spreadsheets()
result = sheet.values().get(spreadsheetId=SAMPLE_SPREADSHEET_ID, range="Sheet1!A1:E100").execute()
values = result.get('values', [])
request = sheet.values().append(spreadsheetId=SAMPLE_SPREADSHEET_ID, range="Sheet1!A1", valueInputOption="USER_ENTERED", insertDataOption="INSERT_ROWS", body={"values":df}).execute()
但它给了我 TypeError: Object of type DataFrame is not JSON serializable
所以我尝试了这个功能,它允许将数据加载和覆盖到 google sheet 但不能附加数据:
def iter_pd(df):
for val in df.columns:
yield val
for row in df.to_numpy():
for val in row:
if pd.isna(val):
yield ""
else:
yield val
def pandas_to_sheets(pandas_df, sheet, clear = True):
# Updates all values in a workbook to match a pandas dataframe
if clear:
sheet.clear()
(row, col) = pandas_df.shape
cells = sheet.range("A1:{}".format(gspread.utils.rowcol_to_a1(row + 1, col)))
for cell, val in zip(cells, iter_pd(pandas_df)):
cell.value = val
sheet.update_cells(cells)
pandas_to_sheets(df, workbook.worksheet("Sheet1"))
如有任何建议,我将不胜感激。
问题
你代码的request变量中的body参数应该是dict类型,你的dataframe应该转换成json.
解决方案
你的 request 变量中的代码应该如下所示(我在我这边复制了这个并且它按预期工作):
request = sheet.values().append(spreadsheetId=SAMPLE_SPREADSHEET_ID, range="Sheet1!A1", valueInputOption="USER_ENTERED", insertDataOption="INSERT_ROWS", body={'values':df.to_json()}).execute()
经过一番调查后,我发现了一种使用 df.to_json()
的方法对我有用:
to_json
returns 一个 json 格式的字符串,工作表 api 需要一个列表。
所以我用了这个电话:
sheet.values().append(
spreadsheetId=SAMPLE_SPREADSHEET_ID,
range="Sheet1!A1",
valueInputOption="USER_ENTERED",
insertDataOption="INSERT_ROWS",
body={
"values": json.loads(df.to_json(orient='values'))
},
).execute()
预先 import json
。
orient='values'
根据工作表 api 的要求将数据格式化为值数组,
json.loads()
将生成的 json-string 解析为 python 对象(列表)
我尝试用 python df 附加 google sheet。 google sheet 授权后,我试了这个:
sheet = service.spreadsheets()
result = sheet.values().get(spreadsheetId=SAMPLE_SPREADSHEET_ID, range="Sheet1!A1:E100").execute()
values = result.get('values', [])
request = sheet.values().append(spreadsheetId=SAMPLE_SPREADSHEET_ID, range="Sheet1!A1", valueInputOption="USER_ENTERED", insertDataOption="INSERT_ROWS", body={"values":df}).execute()
但它给了我 TypeError: Object of type DataFrame is not JSON serializable
所以我尝试了这个功能,它允许将数据加载和覆盖到 google sheet 但不能附加数据:
def iter_pd(df):
for val in df.columns:
yield val
for row in df.to_numpy():
for val in row:
if pd.isna(val):
yield ""
else:
yield val
def pandas_to_sheets(pandas_df, sheet, clear = True):
# Updates all values in a workbook to match a pandas dataframe
if clear:
sheet.clear()
(row, col) = pandas_df.shape
cells = sheet.range("A1:{}".format(gspread.utils.rowcol_to_a1(row + 1, col)))
for cell, val in zip(cells, iter_pd(pandas_df)):
cell.value = val
sheet.update_cells(cells)
pandas_to_sheets(df, workbook.worksheet("Sheet1"))
如有任何建议,我将不胜感激。
问题
你代码的request变量中的body参数应该是dict类型,你的dataframe应该转换成json.
解决方案
你的 request 变量中的代码应该如下所示(我在我这边复制了这个并且它按预期工作):
request = sheet.values().append(spreadsheetId=SAMPLE_SPREADSHEET_ID, range="Sheet1!A1", valueInputOption="USER_ENTERED", insertDataOption="INSERT_ROWS", body={'values':df.to_json()}).execute()
经过一番调查后,我发现了一种使用 df.to_json()
的方法对我有用:
to_json
returns 一个 json 格式的字符串,工作表 api 需要一个列表。
所以我用了这个电话:
sheet.values().append(
spreadsheetId=SAMPLE_SPREADSHEET_ID,
range="Sheet1!A1",
valueInputOption="USER_ENTERED",
insertDataOption="INSERT_ROWS",
body={
"values": json.loads(df.to_json(orient='values'))
},
).execute()
预先 import json
。
orient='values'
根据工作表 api 的要求将数据格式化为值数组,
json.loads()
将生成的 json-string 解析为 python 对象(列表)