特定行的总和 pandas 数据框
sum of specific rows pandas dataframe
我有一个数据框,想将特定行的总和添加到该数据框中。
例如我有
df = pd.DataFrame({'prod':['a','a','a','b','b','b','c','c','c'], 'attribute':['x','y','z','x','y','z','x','y','z'],
'number1':[1,2,2,3,4,3,5,1,1], 'number2':[10,2,3,3,1,2,3,1,1], 'number3':[1,4,3,5,7,1,3,0,1]})
如何为每个产品 a、b 和 c 添加属性 y 和 z 的数字 1/2/3 的总和作为新行?
所以看起来像这样
prod attribute number1 number2 number3
0 a x 1 10 1
1 a y 2 2 4
2 a z 2 3 3
3 a sum_yz 4 5 7
4 b x 3 3 5
5 b y 4 1 7
6 b z 3 2 1
7 b sum_yz 7 3 8
8 c x 5 3 3
9 c y 1 1 0
10 c z 1 1 1
11 c sum_yz 2 2 1
您需要 concat
并且有条件 groupby
。
您可以使用 isin
过滤数据框并使用 assign
添加新列。
首先让我们select目标列求和。
cols = [col for col in df.columns if 'number' in col]
df1 = pd.concat(
[
df,
df[df["attribute"].isin(["y", "z"])]
.groupby("prod")[cols]
.sum()
.assign(attribute="sum_yz")
.reset_index(),
]
).sort_values("prod")
print(df1)
prod attribute number1 number2 number3
0 a x 1 10 1
1 a y 2 2 4
2 a z 2 3 3
0 a sum_yz 4 5 7
3 b x 3 3 5
4 b y 4 1 7
5 b z 3 2 1
1 b sum_yz 7 3 8
6 c x 5 3 3
7 c y 1 1 0
8 c z 1 1 1
2 c sum_yz 2 2 1
您可以创建一个单独的 DataFrame 并将其附加回原始 DataFrame,如下所示(此代码未经测试):
# Filter to the desired attributes
sum_yz = df[df['attribute'].isin(['y', 'z'])]
# Set the new 'attribute' value
sum_yz['attribute'] = 'sum_yz'
# Group by and sum
sum_yz = sum_yz.groupby(['prod', 'attribute']).sum().reset_index()
# Add it the end of the data frame
df = pd.concat([df, sum_yz])
可以使用df.groupby()
然后将groupby-outcome与原来的df合并
# Create groupby DataFrame
df_grp = df[df['attribute'].isin(['y', 'z'])].groupby(['prod']).sum()
df_grp.reset_index(inplace=True)
df_grp['attribute'] = 'sum_yz'
# Combine with original dataframe
df = pd.concat([df, df_grp])
一个关于字典的想法,但如果 DataFrame 很大则更慢:
def f(x):
d = x[x['attribute'].isin(['y','z'])].sum()
d1 = {'prod': x.name, 'attribute':'sum_yz'}
x = x.append({**d, **d1},ignore_index=True)
return x
df = df.groupby('prod', sort=False).apply(f).reset_index(drop=True)
print (df)
prod attribute number1 number2 number3
0 a x 1 10 1
1 a y 2 2 4
2 a z 2 3 3
3 a sum_yz 4 5 7
4 b x 3 3 5
5 b y 4 1 7
6 b z 3 2 1
7 b sum_yz 7 3 8
8 c x 5 3 3
9 c y 1 1 0
10 c z 1 1 1
11 c sum_yz 2 2 1
或者如果可能的话,产品的排序值首先按 Series.isin
, aggregate sum
, add to original with replace NaN
by DataFrame.fillna
and last sorting by DataFrame.sort_values
过滤,默认索引为 ignore_index
:
df = (df.append(df[df['attribute'].isin(['y', 'z'])]
.groupby('prod', as_index=False)
.sum()
).fillna({'attribute': 'sum_yz'})
.sort_values('prod', ignore_index=True))
print (df)
prod attribute number1 number2 number3
0 a x 1 10 1
1 a y 2 2 4
2 a z 2 3 3
3 a sum_yz 4 5 7
4 b x 3 3 5
5 b y 4 1 7
6 b z 3 2 1
7 b sum_yz 7 3 8
8 c x 5 3 3
9 c y 1 1 0
10 c z 1 1 1
11 c sum_yz 2 2 1
您可以在 groupby 之后使用 pandas concat :
result = df.groupby(["prod", df.attribute.isin(["y", "z"])]).sum().loc[:, True, :]
result = result.reset_index()
result.insert(1, "attribute", "sum_yz")
pd.concat([df, result]).sort_values("prod", ignore_index=True)
prod attribute number1 number2 number3
0 a x 1 10 1
1 a y 2 2 4
2 a z 2 3 3
3 a sum_yz 4 5 7
4 b x 3 3 5
5 b y 4 1 7
6 b z 3 2 1
7 b sum_yz 7 3 8
8 c x 5 3 3
9 c y 1 1 0
10 c z 1 1 1
11 c sum_yz 2 2 1
这很简单而且工作正常
dr=df[df['attribute']!='x'].groupby('prod').sum().reset_index()
dr['attribute']='sum_yz'
result=pd.concat([df,dr]).sort_values('prod')
我有一个数据框,想将特定行的总和添加到该数据框中。 例如我有
df = pd.DataFrame({'prod':['a','a','a','b','b','b','c','c','c'], 'attribute':['x','y','z','x','y','z','x','y','z'],
'number1':[1,2,2,3,4,3,5,1,1], 'number2':[10,2,3,3,1,2,3,1,1], 'number3':[1,4,3,5,7,1,3,0,1]})
如何为每个产品 a、b 和 c 添加属性 y 和 z 的数字 1/2/3 的总和作为新行? 所以看起来像这样
prod attribute number1 number2 number3
0 a x 1 10 1
1 a y 2 2 4
2 a z 2 3 3
3 a sum_yz 4 5 7
4 b x 3 3 5
5 b y 4 1 7
6 b z 3 2 1
7 b sum_yz 7 3 8
8 c x 5 3 3
9 c y 1 1 0
10 c z 1 1 1
11 c sum_yz 2 2 1
您需要 concat
并且有条件 groupby
。
您可以使用 isin
过滤数据框并使用 assign
添加新列。
首先让我们select目标列求和。
cols = [col for col in df.columns if 'number' in col]
df1 = pd.concat(
[
df,
df[df["attribute"].isin(["y", "z"])]
.groupby("prod")[cols]
.sum()
.assign(attribute="sum_yz")
.reset_index(),
]
).sort_values("prod")
print(df1)
prod attribute number1 number2 number3
0 a x 1 10 1
1 a y 2 2 4
2 a z 2 3 3
0 a sum_yz 4 5 7
3 b x 3 3 5
4 b y 4 1 7
5 b z 3 2 1
1 b sum_yz 7 3 8
6 c x 5 3 3
7 c y 1 1 0
8 c z 1 1 1
2 c sum_yz 2 2 1
您可以创建一个单独的 DataFrame 并将其附加回原始 DataFrame,如下所示(此代码未经测试):
# Filter to the desired attributes
sum_yz = df[df['attribute'].isin(['y', 'z'])]
# Set the new 'attribute' value
sum_yz['attribute'] = 'sum_yz'
# Group by and sum
sum_yz = sum_yz.groupby(['prod', 'attribute']).sum().reset_index()
# Add it the end of the data frame
df = pd.concat([df, sum_yz])
可以使用df.groupby()
然后将groupby-outcome与原来的df合并
# Create groupby DataFrame
df_grp = df[df['attribute'].isin(['y', 'z'])].groupby(['prod']).sum()
df_grp.reset_index(inplace=True)
df_grp['attribute'] = 'sum_yz'
# Combine with original dataframe
df = pd.concat([df, df_grp])
一个关于字典的想法,但如果 DataFrame 很大则更慢:
def f(x):
d = x[x['attribute'].isin(['y','z'])].sum()
d1 = {'prod': x.name, 'attribute':'sum_yz'}
x = x.append({**d, **d1},ignore_index=True)
return x
df = df.groupby('prod', sort=False).apply(f).reset_index(drop=True)
print (df)
prod attribute number1 number2 number3
0 a x 1 10 1
1 a y 2 2 4
2 a z 2 3 3
3 a sum_yz 4 5 7
4 b x 3 3 5
5 b y 4 1 7
6 b z 3 2 1
7 b sum_yz 7 3 8
8 c x 5 3 3
9 c y 1 1 0
10 c z 1 1 1
11 c sum_yz 2 2 1
或者如果可能的话,产品的排序值首先按 Series.isin
, aggregate sum
, add to original with replace NaN
by DataFrame.fillna
and last sorting by DataFrame.sort_values
过滤,默认索引为 ignore_index
:
df = (df.append(df[df['attribute'].isin(['y', 'z'])]
.groupby('prod', as_index=False)
.sum()
).fillna({'attribute': 'sum_yz'})
.sort_values('prod', ignore_index=True))
print (df)
prod attribute number1 number2 number3
0 a x 1 10 1
1 a y 2 2 4
2 a z 2 3 3
3 a sum_yz 4 5 7
4 b x 3 3 5
5 b y 4 1 7
6 b z 3 2 1
7 b sum_yz 7 3 8
8 c x 5 3 3
9 c y 1 1 0
10 c z 1 1 1
11 c sum_yz 2 2 1
您可以在 groupby 之后使用 pandas concat :
result = df.groupby(["prod", df.attribute.isin(["y", "z"])]).sum().loc[:, True, :]
result = result.reset_index()
result.insert(1, "attribute", "sum_yz")
pd.concat([df, result]).sort_values("prod", ignore_index=True)
prod attribute number1 number2 number3
0 a x 1 10 1
1 a y 2 2 4
2 a z 2 3 3
3 a sum_yz 4 5 7
4 b x 3 3 5
5 b y 4 1 7
6 b z 3 2 1
7 b sum_yz 7 3 8
8 c x 5 3 3
9 c y 1 1 0
10 c z 1 1 1
11 c sum_yz 2 2 1
这很简单而且工作正常
dr=df[df['attribute']!='x'].groupby('prod').sum().reset_index()
dr['attribute']='sum_yz'
result=pd.concat([df,dr]).sort_values('prod')