如何使用多索引df中的两行执行计算,并将结果追加为新行?

2024-07-04 17:32:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样一个多索引df:

                 foo  bar  now
2018-01-01 row1    0    1    2
           row2    3    4    5
           row3    6    7    8
           row4    9   10   11
2018-01-02 row1   12   13   14
           row2   15   16   17
           row3   18   19   20
           row4   21   22   23
2018-01-03 row1   24   25   26
           row2   27   28   29
           row3   30   31   32
           row4   33   34   35

我想添加一个新的row5,其中包含使用其他level1行执行的计算的值,例如:row1*row3

计算步骤的结果应为:

                 foo  bar  now
2018-01-01 row5    0    7   16
2018-01-02 row5   etc..
2018-01-03 row5   etc..

一旦新行被附加到原始行,结果df将如下所示:

                 foo  bar  now
2018-01-01 row1    0    1    2
           row2    3    4    5
           row3    6    7    8
           row4    9   10   11
           row5    0    7   16
2018-01-02 row1   12   13   14
           row2   15   16   17
           row3   18   19   20
           row4   21   22   23
           row5   etc...
2018-01-03 row1   24   25   26
           row2   27   28   29
           row3   30   31   32
           row4   33   34   35
           row5   etc...

我可以用这种方式计算所有行的输出值,但这不是我想要的:

df.loc[pd.IndexSlice[:,:], :] * df.loc[pd.IndexSlice[:,:], :]

我认为广播不起作用,所以我打算尝试一个循环,但我无法使计算起作用(返回一个df,其中第1行和第3行都是NaN的):

df.loc[pd.IndexSlice['2018-01-01', 'row1'], :] * df.loc[pd.IndexSlice['2018-01-01', 'row3'], :]

提前感谢您提供的任何解决方案、提示和参考资源:)


Tags: dffooetcbar步骤nowlocpd
2条回答

您可以在第一个索引级别上使用对齐方式进行计算,手动向后分配第二个级别,然后进行连接和排序:

import pandas as pd

idx = pd.IndexSlice
newdf = ((df.loc[idx[:, 'row1'], :].reset_index(level=1, drop=True)
          *df.loc[idx[:, 'row3'], :].reset_index(level=1, drop=True))
          .assign(idx1='row5')
          .set_index('idx1', append=True)
          .rename_axis([None, None]))

df = pd.concat([df, newdf]).sort_index()

输出:

                 foo  bar  now
2018-01-01 row1    0    1    2
           row2    3    4    5
           row3    6    7    8
           row4    9   10   11
           row5    0    7   16
2018-01-02 row1   12   13   14
           row2   15   16   17
           row3   18   19   20
           row4   21   22   23
           row5  216  247  280
2018-01-03 row1   24   25   26
           row2   27   28   29
           row3   30   31   32
           row4   33   34   35
           row5  720  775  832

这里有一个方法

s=df.loc[pd.IndexSlice[:,'row1'],:]*df.loc[pd.IndexSlice[:,'row3'],:].values
s=s.reset_index(level=1).assign(level_1='row5').set_index('level_1',append=True)
pd.concat([df,s]).sort_index()
                 foo  bar  now
2018-01-01 row1    0    1    2
           row2    3    4    5
           row3    6    7    8
           row4    9   10   11
           row5    0    7   16
2018-01-02 row1   12   13   14
           row2   15   16   17
           row3   18   19   20
           row4   21   22   23
           row5  216  247  280
2018-01-03 row1   24   25   26
           row2   27   28   29
           row3   30   31   32
           row4   33   34   35
           row5  720  775  832

相关问题 更多 >

    热门问题