簡體   English   中英

特定行的總和 pandas dataframe

[英]sum of specific rows pandas dataframe

我有一個 dataframe 並且想將特定行的總和添加到這個 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 過濾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

您可以將單獨的 DataFrane 和 append 重新設置為原始 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過濾產品的排序值,聚合sum ,添加到原始值,用DataFrame.sort_values替換NaN ,最后通過DataFrame.fillna排序,默認索引為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')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM