![](/img/trans.png)
[英]Uploading a multiindex dataframe to google sheets using df2gspread
[英]MultiIndex pandas dataframe and writing to Google Sheets using gspread-pandas
从以下字典开始:
test_dict = {'header1_1': {'header2_1': {'header3_1': {'header4_1': ['322.5', 330.0, -0.28],
'header4_2': ['322.5', 332.5, -0.26]},
'header3_2': {'header4_1': ['285.0', 277.5, -0.09],
'header4_2': ['287.5', 277.5, -0.12]}},
'header2_2': {'header3_1': {'header4_1': ['345.0', 357.5, -0.14],
'header4_2': ['345.0', 362.5, -0.14]},
'header3_2': {'header4_1': ['257.5', 245.0, -0.1],
'header4_2': ['257.5', 240.0, -0.08]}}}}
我想要索引中的标题,所以我修改了字典:
reformed_dict = {}
for outerKey, innerDict in test_dict.items():
for innerKey, innerDict2 in innerDict.items():
for innerKey2, innerDict3 in innerDict2.items():
for innerKey3, values in innerDict3.items():
reformed_dict[(outerKey,
innerKey, innerKey2, innerKey3)] = values
并将列名分配给标题:
keys = reformed_dict.keys()
values = reformed_dict.values()
index = pd.MultiIndex.from_tuples(keys, names=["H1", "H2", "H3", "H4"])
df = pd.DataFrame(data=values, index=index)
Issue #1 [*** @AzharKhan 已经回答了这个问题,所以请随意跳到 Issue #2 ***]:要为数据列分配名称,我尝试过:
df.columns = ['col 1', 'col 2' 'col 3']
并得到错误:“ValueError:长度不匹配:预期轴有 3 个元素,新值有 2 个元素”
然后根据建议,我尝试了:
df = df.rename(columns={'0': 'Col1', '1': 'Col2', '2': 'Col3'})
这不会产生错误,但 dataframe 看起来和以前完全一样,数据列标题为 0、1、2。
如何为这些数据列分配名称? 我假设 0、1、2 是列索引,而不是列名。
问题 #2 :当我使用gspread-pandas将此 dataframe 写入 Google 表格时:
s.open_sheet('test')
Spread.df_to_sheet(s, df, index=True, headers=True, start='A8', replace=False)
这是之前 Jupyter notebook 截图中的 dataframe 是这样出现的,所以看起来写入电子表格的过程似乎是在填充空行标题,这使得表格很难一目了然。
我怎样才能得到 output 到电子表格以省略行标题,直到它们发生变化,从而得到第二个电子表格 output?
问题 #1
您的列是数字(不是字符串)。 您可以通过以下方式查看:
print(df.columns)
[Out]:
RangeIndex(start=0, stop=3, step=1)
在df.rename()
中使用数字,如下所示:
df = df.rename(columns={0: 'Col1', 1: 'Col2', 2: 'Col3'})
print(df.columns)
print(df)
[Out]:
Index(['Col1', 'Col2', 'Col3'], dtype='object')
Col1 Col2 Col3
H1 H2 H3 H4
header1_1 header2_1 header3_1 header4_1 322.5 330.0 -0.28
header4_2 322.5 332.5 -0.26
header3_2 header4_1 285.0 277.5 -0.09
header4_2 287.5 277.5 -0.12
header2_2 header3_1 header4_1 345.0 357.5 -0.14
header4_2 345.0 362.5 -0.14
header3_2 header4_1 257.5 245.0 -0.10
header4_2 257.5 240.0 -0.08
或者,如果您想概括它而不是硬编码,请使用:
df = df.rename(columns={i:f"Col{i+1}" for i in df.columns})
我不确定你的问题#2。 你可能想把它分成一个单独的问题来引起注意。
这是使用pd.json_normalize()
处理问题 #1 的方法
df = pd.json_normalize(test_dict,max_level=3).stack().droplevel(0)
idx = df.index.map(lambda x: tuple(x.split('.'))).rename(['H1','H2','H3','H4'])
df = pd.DataFrame(df.tolist(),index = idx,columns = ['col1','col2','col3'])
Output:
col1 col2 col3
H1 H2 H3 H4
header1_1 header2_1 header3_1 header4_1 322.5 330.0 -0.28
header4_2 322.5 332.5 -0.26
header3_2 header4_1 285.0 277.5 -0.09
header4_2 287.5 277.5 -0.12
header2_2 header3_1 header4_1 345.0 357.5 -0.14
header4_2 345.0 362.5 -0.14
header3_2 header4_1 257.5 245.0 -0.10
header4_2 257.5 240.0 -0.08
问题 #2 很棘手,因为 Jupyter notebook 显示带有“空白”值的索引,但如果您要执行df.index
,它会显示所有数据实际上都在那里。 它只是 Jupyter 笔记本使用的视觉选择。
为了实现这一点,您可以检查值的变化并加入新创建的 df。
idx_df = df.index.to_frame().reset_index(drop=True)
df = idx_df.where(idx_df.ne(idx_df.shift())).join(df.reset_index(drop=True))
gspread-pandas 的创建者添加了在将 dataframe 写入 Google 表格时合并索引的功能。 它还没有在 gspread-pandas 的一般发布版本中,但可以在这里找到: https://github.com/aiguofer/gspread-pandas/pull/92
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.