为了账号安全,请及时绑定邮箱和手机立即绑定

如何从具有多级重复列的 excel 表中取消堆叠 df?设置多索引?

如何从具有多级重复列的 excel 表中取消堆叠 df?设置多索引?

素胚勾勒不出你 2023-06-13 16:03:34
df 从 xlsx 读取:df = pd.read_excel('file.xlsx')像这样到达:   Age Male Female Male.1 Female.10  NaN  Big  Small  Small      Big1  1.0    2      3      2        32  2.0    3      4      3        43  3.0    4      5      4        5df = pd.DataFrame({'Age':[np.nan, 1,2,3],'Male':['Big',2,3,4],'Female':['Small',3,4,5],'Male.1':['Small',2,3,4],'Female.1':['Big',3,4,5]})注意 Pandas 为重复的列添加后缀.1,这是不希望的。我想拆开/融化以获得这个或类似的东西:    Age Gender  Size    [measure]1   1   Male    Big     22   2   Male    Big     33   3   Male    Big     44   1   Female  Big     35   2   Female  Big     46   3   Female  Big     57   1   Male    Small   28   2   Male    Small   39   3   Male    Small   410  1   Female  Small   311  2   Female  Small   412  3   Female  Small   5重命名列和取消堆叠接近但没有雪茄:df= df.rename(columns={'Male.1': 'Male', 'Female.1':'Female'})df= df.set_index(['Age']).unstack()如何将第一行设置为列的第二个索引级别?
查看完整描述

3 回答

?
芜湖不芜

TA贡献1796条经验 获得超7个赞

而不是.unstack(),另一种方法是.melt()。


您可以使用 转置数据框,并.T使用 获取第一行之后的所有内容.iloc[1:]。然后,.rename列、.replace带有.1一些正则表达式的.melt数据框和.sort_values.


df = pd.DataFrame({'Age':[np.nan, 1,2,3],'Male':['Big',2,3,4],'Female':['Small',3,4,5],'Male.1':['Small',2,3,4],'Female.1':['Big',3,4,5]})

df = (df.T.reset_index().iloc[1:]

      .rename({'index' : 'Gender', 0 : 'Size'}, axis=1)

      .replace(r'\.\d+$', '', regex=True)

      .melt(id_vars=['Gender', 'Size'], value_name='[measure]', var_name='Age')

      .sort_values(['Size', 'Gender', 'Age'], ascending=[True,False,True])

      .reset_index(drop=True))

df = df[['Age', 'Gender', 'Size', '[measure]']]      

df

Out[41]: 

   Age  Gender   Size  [measure]

0    1    Male    Big          2

1    2    Male    Big          3

2    3    Male    Big          4

3    1  Female    Big          3

4    2  Female    Big          4

5    3  Female    Big          5

6    1    Male  Small          2

7    2    Male  Small          3

8    3    Male  Small          4

9    1  Female  Small          3

10   2  Female  Small          4

11   3  Female  Small          5


查看完整回答
反对 回复 2023-06-13
?
慕哥6287543

TA贡献1831条经验 获得超10个赞

如果可能,创建前 2 行MultiIndex和第一列作为索引依据headerindex_col参数 in read_excel

df = pd.read_excel('file.xlsx',header=[0,1], index_col=[0])

    

print (df)

Age Male Female  Male Female

     Big  Small Small    Big

1.0    2      3     2      3

2.0    3      4     3      4

3.0    4      5     4      5


print (df.columns)

MultiIndex([(  'Male',   'Big'),

            ('Female', 'Small'),

            (  'Male', 'Small'),

            ('Female',   'Big')],

           names=['Age', None])


print (df.index)

Float64Index([1.0, 2.0, 3.0], dtype='float64')

所以可能使用DataFrame.unstack

df = (df.unstack()

        .rename_axis(['Gender', 'Size','Age'])

        .reset_index(name='measure'))

print (df)

    Gender   Size  Age  measure

0     Male    Big  1.0        2

1     Male    Big  2.0        3

2     Male    Big  3.0        4

3   Female  Small  1.0        3

4   Female  Small  2.0        4

5   Female  Small  3.0        5

6     Male  Small  1.0        2

7     Male  Small  2.0        3

8     Male  Small  3.0        4

9   Female    Big  1.0        3

10  Female    Big  2.0        4

11  Female    Big  3.0        5

如果不可能使用:

您可以创建MultiIndexMultiIndex.from_arrays删除最后一个.数字 by replace,然后过滤掉第一行DataFrame.iloc并按DataFrame.melt第一列重塑形状,最后设置新的列名称:

df.columns = pd.MultiIndex.from_arrays([df.columns.str.replace(r'\.\d+$', ''), 

                                        df.iloc[0]])

df = df.iloc[1:].melt(df.columns[:1].tolist())

df.columns=['Age','Gender','Size','measure']

print (df)

    Age  Gender   Size measure

0   1.0    Male    Big       2

1   2.0    Male    Big       3

2   3.0    Male    Big       4

3   1.0  Female  Small       3

4   2.0  Female  Small       4

5   3.0  Female  Small       5

6   1.0    Male  Small       2

7   2.0    Male  Small       3

8   3.0    Male  Small       4

9   1.0  Female    Big       3

10  2.0  Female    Big       4

11  3.0  Female    Big       5

或者解决方案DataFrame.unstack是可能的,只将第一列设置为indexby并为新列名称设置byDataFrame.set_index的级别:MultiIndexSeries.rename_axis

df.columns = pd.MultiIndex.from_arrays([df.columns.str.replace(r'\.\d+$', ''), 

                                        df.iloc[0]])

df = (df.iloc[1:].set_index(df.columns[:1].tolist())

        .unstack()

        .rename_axis(['Gender', 'Size','Age'])

        .reset_index(name='measure'))

print (df)

    Gender   Size  Age measure

0     Male    Big  1.0       2

1     Male    Big  2.0       3

2     Male    Big  3.0       4

3   Female  Small  1.0       3

4   Female  Small  2.0       4

5   Female  Small  3.0       5

6     Male  Small  1.0       2

7     Male  Small  2.0       3

8     Male  Small  3.0       4

9   Female    Big  1.0       3

10  Female    Big  2.0       4

11  Female    Big  3.0       5


查看完整回答
反对 回复 2023-06-13
?
蛊毒传说

TA贡献1895条经验 获得超3个赞

通过将行 0 与列组合来创建多索引列:


df.columns = pd.MultiIndex.from_arrays((df.columns, df.iloc[0]))

df.columns.names = ['gender', 'size']


df.columns


MultiIndex([(     'Age',     nan),

            (    'Male',   'Big'),

            (  'Female', 'Small'),

            (  'Male.1', 'Small'),

            ('Female.1',   'Big')],

          names=['gender', 'size'])

现在您可以重塑和重命名:


 (df

  .dropna()

  .melt([('Age', np.NaN)], value_name='measure')

  .replace(r'\.\d+$', '', regex=True)

  .rename(columns={("Age", np.NaN) : "Age"}))


   Age  gender  size measure

0   1.0 Male    Big     2

1   2.0 Male    Big     3

2   3.0 Male    Big     4

3   1.0 Female  Small   3

4   2.0 Female  Small   4

5   3.0 Female  Small   5

6   1.0 Male    Small   2

7   2.0 Male    Small   3

8   3.0 Male    Small   4

9   1.0 Female  Big     3

10  2.0 Female  Big     4

11  3.0 Female  Big     5


查看完整回答
反对 回复 2023-06-13
  • 3 回答
  • 0 关注
  • 122 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信