基于特定条件的动态列的总和

时间:2019-06-25 17:33:53

标签: python pandas dataframe

我正在尝试根据特定条件获取动态列的总和。

cols = ['ID','A','B','C','D','E','F','G']

dataframe df具有上面列出的所有列。

如果ID = 2,则需要前两列A,B的总和 如果ID = 3,则需要前三列A,B,C的总和

df.loc['SUM'] = df.loc[df['ID'] > 0,cols[0:df['ID']]].sum(axis=1)

上面的代码给出的错误是:

TypeError: slice indices must be integers or None or have an __index__ method

注意: ID可以是任何数字,但始终小于或等于列总数

数据框中没有nan和缺少值。

2 个答案:

答案 0 :(得分:3)

借助NumPy的强大功能,您可以实现矢量化:

df.set_index('ID', inplace=True)
df.wherenp.arange(df.shape[1]) < df.index.values[:,None]).sum(axis=1)    

最小可复制示例

import pandas as pd

pd.__version__
# '0.24.2'

np.random.seed(0) 
df = pd.DataFrame(np.random.randint(1, 10, (5, 8))) 
df.insert(0, 'ID', np.random.randint(1, 8, 5))  
df                                           

   ID  0  1  2  3  4  5  6  7
0   4  6  1  4  4  8  4  6  3
1   7  5  8  7  9  9  2  7  8
2   4  8  9  2  6  9  5  4  1
3   3  4  6  1  3  4  9  2  4
4   5  4  4  8  1  2  1  5  8

df.set_index('ID', inplace=True)
df.assign(
    SUM=df.where(np.arange(df.shape[1]) < df.index.values[:,None]).sum(axis=1))

    0  1  2  3  4  5  6  7   SUM
ID                              
4   6  1  4  4  8  4  6  3  15.0
7   5  8  7  9  9  2  7  8  47.0
4   8  9  2  6  9  5  4  1  25.0
3   4  6  1  3  4  9  2  4  11.0
5   4  4  8  1  2  1  5  8  19.0

where函数将隐藏我们不想求和的值:

df.where(np.arange(df.shape[1]) < df.index[:,None])   

    0  1  2    3    4    5    6   7
ID                                 
4   6  1  4  4.0  NaN  NaN  NaN NaN
7   5  8  7  9.0  9.0  2.0  7.0 NaN
4   8  9  2  6.0  NaN  NaN  NaN NaN
3   4  6  1  NaN  NaN  NaN  NaN NaN
5   4  4  8  1.0  2.0  NaN  NaN NaN

感谢@Quang Hoang指出了解决方案中的潜在错误。

答案 1 :(得分:1)

另一种方式:

带有df:

    0  1  2  3  4  5  6  7   
ID                              
4   6  1  4  4  8  4  6  3  
7   5  8  7  9  9  2  7  8  
4   8  9  2  6  9  5  4  1 
3   4  6  1  3  4  9  2  4  
5   4  4  8  1  2  1  5  8  

总和由df.cumsum(axis=1).values[range(len(df)),df.index-1]

计算

它比df.where(np.arange(df.shape[1]) <df.index.values[:,None]).sum(axis=1)快5倍。