【问题标题】:How to subtract a in second level columns in multiIndex level dataframe如何在 multiIndex 级数据框中的第二级列中减去 a
【发布时间】:2022-11-29 14:50:39
【问题描述】:

这是我正在使用的示例数据。我想要完成的是 1) 从 a 列减去 b 列和 2) 在 a 和 b 列前面创建 C 列。我想遍历并为 x、y 和 z 创建 C 列。

import pandas as pd
df = pd.DataFrame(data=[[100,200,400,500,111,222], [77,28,110,211,27,81], [11,22,33,11,22,33],[213,124,136,147,54,56]])
df.columns = pd.MultiIndex.from_product([['x', 'y', 'z'], list('ab')])
print (df)

以下是我想要得到的。

【问题讨论】:

  • 通过文本或图像进行不期望的输出
  • 我附上了图片

标签: python pandas dataframe pivot-table multi-index


【解决方案1】:

使用DataFrame.xs选择第二级,避免使用drop_level=False删除第一级,然后使用rename用于相同的MultiIndex,使用concat减去并添加到原始,最后使用DataFrame.sort_index

dfa = df.xs('a', axis=1, level=1, drop_level=False).rename(columns={'a':'c'})
dfb = df.xs('b', axis=1, level=1, drop_level=False).rename(columns={'b':'c'})

df = pd.concat([df, dfa.sub(dfb)], axis=1).sort_index(axis=1)
print (df)
     x              y              z          
     a    b    c    a    b    c    a    b    c
0  100  200 -100  400  500 -100  111  222 -111
1   77   28   49  110  211 -101   27   81  -54
2   11   22  -11   33   11   22   22   33  -11
3  213  124   89  136  147  -11   54   56   -2

通过元组循环选择列,减去 Series 并最后使用 DataFrame.sort_index

for c in df.columns.levels[0]:
    df[(c, 'c')] = df[(c, 'a')].sub(df[(c, 'b')])

df = df.sort_index(axis=1)
print (df)
     x              y              z          
     a    b    c    a    b    c    a    b    c
0  100  200 -100  400  500 -100  111  222 -111
1   77   28   49  110  211 -101   27   81  -54
2   11   22  -11   33   11   22   22   33  -11
3  213  124   89  136  147  -11   54   56   -2

【讨论】:

  • 非常好,杰斯瑞尔!甚至提供两种选择。也感谢您提供详细的解释。
  • 只是好奇。哪个选项会更好?这是第一个选项,因为不涉及循环吗?
  • @yeppi - 这取决于数据,我想如果有很多组 len(df.columns.levels[0]) 那么第一个应该更好,如果几个组那么第二个。
【解决方案2】:
a = df.xs('a', level=1, axis=1)
b = df.xs('b', level=1, axis=1)
df1 = pd.concat([a.sub(b)], keys=['c'], axis=1).swaplevel(0, 1, axis=1)

df1

    x       y       z
    c       c       c
0   -100    -100    -111
1   49      -101    -54
2   -11       22    -11
3   89       -11    -2

然后首先连接 df 和 df1 ,下一个排序

pd.concat([df, df1], axis=1).sort_index(axis=1)



另一种方式

使用堆栈和取消堆栈

df.stack(level=0).assign(c=lambda x: x['b'] - x['a']).stack().unstack([1, 2])

结果:

    x           y           z
    a   b   c   a   b   c   a   b   c
0   100 200 100 400 500 100 111 222 111
1   77  28  -49 110 211 101 27  81  54
2   11  22  11  33  11  -22 22  33  11
3   213 124 -89 136 147 11  54  56  2

【讨论】:

  • 非常感谢,熊猫!这非常有帮助。我会选择另一个答案,因为他回来得快一点。
  • 我不在乎你选择什么。别担心。我编辑并附加了新答案。给你检查一下!
  • 非常感谢你,熊猫。
猜你喜欢
  • 2022-01-08
  • 2017-07-03
  • 2017-12-21
  • 2019-09-04
  • 1970-01-01
  • 2021-10-20
  • 2017-06-13
相关资源
最近更新 更多