行值等于标头的总和-熊猫

时间:2020-06-02 00:24:02

标签: python pandas

我正在尝试对pandas df中的列求和,其中列等于特定值。使用下面的df,在['X'] == 'GrV'中,我想对cols ('GrV A', 'GrV B')求和。但是我返回的是nan值。

import pandas as pd

df = pd.DataFrame({
    'X' : ['GrV', 'GrX', 'GrY', 'GrZ', 'GrV', 'GrX', 'GrY', 'GrZ'],  
    'GrV A' : [4, 2, 6, 5, 1, 2, 5, 6],                  
    'GrX A' : [3, 4, 5, 1, 2, 5, 6, 2], 
    'GrY A' : [5, 2, 2, 6, 5, 1, 5, 4],
    'GrZ A' : [1, 2, 5, 5, 2, 1, 5, 4], 
    'GrV B' : [4, 2, 6, 5, 1, 2, 5, 6],                  
    'GrX B' : [3, 4, 5, 1, 2, 5, 6, 2], 
    'GrY B' : [5, 2, 2, 6, 5, 1, 5, 4],
    'GrZ B' : [1, 2, 5, 5, 2, 1, 5, 4],                            
        })

df['Total'] = df.loc[(df['X'] == 'GrV'), ('GrV A', 'GrV B')].sum()
df['Total'] = df.loc[(df['X'] == 'GrX'), ('GrX A', 'GrX B')].sum()
df['Total'] = df.loc[(df['X'] == 'GrY'), ('GrY A', 'GrY B')].sum()
df['Total'] = df.loc[(df['X'] == 'GrZ'), ('GrZ A', 'GrZ B')].sum()

预期输出:

     X  GrV A  GrX A  GrY A  GrZ A  GrV B  GrX B  GrY B  GrZ B  Total
0  GrV      4      3      5      1      4      3      5      1      8
1  GrX      2      4      2      2      2      4      2      2      8
2  GrY      6      5      2      5      6      5      2      5      4
3  GrZ      5      1      6      5      5      1      6      5     10
4  GrV      1      2      5      2      1      2      5      2      2
5  GrX      2      5      1      1      2      5      1      1     10
6  GrY      5      6      5      5      5      6      5      5     10
7  GrZ      6      2      4      4      6      2      4      4      8

4 个答案:

答案 0 :(得分:2)

您可以使用filter获取列Gr,使用wheresplit(获得的列名的第一个元素来获取GrV,GrX,...部分)等于X列和sum列:

df['Total'] = (df.filter(like='Gr')
                 .where(lambda x: df['X'].to_numpy()[:, None]
                                  == x.columns.str.split(' ').str[0].to_numpy())
                 .sum(axis=1)
              )
print (df)
     X  GrV A  GrX A  GrY A  GrZ A  GrV B  GrX B  GrY B  GrZ B  Total
0  GrV      4      3      5      1      4      3      5      1    8.0
1  GrX      2      4      2      2      2      4      2      2    8.0
2  GrY      6      5      2      5      6      5      2      5    4.0
3  GrZ      5      1      6      5      5      1      6      5   10.0
4  GrV      1      2      5      2      1      2      5      2    2.0
5  GrX      2      5      1      1      2      5      1      1   10.0
6  GrY      5      6      5      5      5      6      5      5   10.0
7  GrZ      6      2      4      4      6      2      4      4    8.0

答案 1 :(得分:1)

这是一种解决方法:将X列附加到索引,获取一对索引和各列的对,其中可以在各列中找到新索引中的值,使用所得值对数据帧进行索引(带有{{1 }}),堆叠,拆堆并得到总数

loc

答案 2 :(得分:1)

这是另一种方式:

for col in df['X'].tolist():
    df['Total_'+col] = np.where(df['X']==col, df[col+' A'] + df[col+' B'], np.NaN)

cols = [col for col in df.columns if col.startswith('Total_')]
df['Total'] = df[cols].sum(axis=1)
df.drop(columns=cols, inplace=True)
print(df)

     X  GrV A  GrX A  GrY A  GrZ A  GrV B  GrX B  GrY B  GrZ B  Total
0  GrV      4      3      5      1      4      3      5      1    8.0
1  GrX      2      4      2      2      2      4      2      2    8.0
2  GrY      6      5      2      5      6      5      2      5    4.0
3  GrZ      5      1      6      5      5      1      6      5   10.0
4  GrV      1      2      5      2      1      2      5      2    2.0
5  GrX      2      5      1      1      2      5      1      1   10.0
6  GrY      5      6      5      5      5      6      5      5   10.0
7  GrZ      6      2      4      4      6      2      4      4    8.0

答案 3 :(得分:0)

让我们尝试meltgroupby

s=df.reset_index().melt(['index','X']).loc[lambda x : x['X']==x['variable'].str.split(' ').str[0]].groupby('index').value.sum()
df['new']=s
df
     X  GrV A  GrX A  GrY A  GrZ A  GrV B  GrX B  GrY B  GrZ B  new
0  GrV      4      3      5      1      4      3      5      1    8
1  GrX      2      4      2      2      2      4      2      2    8
2  GrY      6      5      2      5      6      5      2      5    4
3  GrZ      5      1      6      5      5      1      6      5   10
4  GrV      1      2      5      2      1      2      5      2    2
5  GrX      2      5      1      1      2      5      1      1   10
6  GrY      5      6      5      5      5      6      5      5   10
7  GrZ      6      2      4      4      6      2      4      4    8