我正在尝试对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
答案 0 :(得分:2)
您可以使用filter
获取列Gr,使用where
由split
(获得的列名的第一个元素来获取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)
让我们尝试melt
与groupby
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