![](/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.