python 使用gspread-pandas创建多索引pandas Dataframe 并写入Google工作表

cmssoen2  于 2022-11-27  发布在  Python
关注(0)|答案(2)|浏览(173)

从以下字典开始:

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)

这样得到的 Dataframe 如下所示:

问题#1[此问题已由@AzharKhan回答,请随意跳至问题#2]:为了给数据列指定名称,我尝试了以下方法:

df.columns = ['col 1', 'col 2' 'col 3']

出现错误:“值错误:长度不匹配:预期轴有3个元素,新值有2个元素”
然后每一个建议,我试着:

df = df.rename(columns={'0': 'Col1', '1': 'Col2', '2': 'Col3'})

这不会产生错误,但 Dataframe 看起来与以前完全相同,数据列标题为0、1、2。
如何为这些数据列指定名称?我假设0、1、2是列索引,而不是列名称。

问题#2:当我使用gspread-pandas将此 Dataframe 写入Google Sheets时:

s.open_sheet('test')
Spread.df_to_sheet(s, df, index=True, headers=True, start='A8', replace=False)

结果是这样的:

我想要的是:

这就是Jupyter笔记本屏幕截图中数据框的显示方式,因此写入电子表格的过程似乎是填充空行标题,这使得表格更难一目了然。
如何将输出输出到电子表格以忽略行标题,直到它们发生更改,从而获得第二个电子表格输出?

omhiaaxx

omhiaaxx1#

问题#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})

我不确定您的第二个问题。您可能需要将其划分为一个单独的问题以引起注意。

wpcxdonn

wpcxdonn2#

下面是使用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'])

输出量:

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

第二个问题很棘手,因为Jupyter笔记本显示的索引值为“空白”,但如果您执行df.index,它会显示所有数据实际上都在那里。这只是Jupyter笔记本使用的一个视觉选择。

相关问题