基于列条件在pandas中求和

unftdfkk  于 2023-11-15  发布在  其他
关注(0)|答案(4)|浏览(170)

我有一个框架(df1),它看起来像这样:

Date                  Name          Category      #
01/01/01              Vegetables       A          15
01/01/01              Fruits           A          10
01/01/01              Meat             B          35
01/02/01              Vegetables       A           7
01/03/01              Vegetables       A           9
01/03/01              No Data         No Data    No Data

字符串
我想创建另一个类似这样的框架(df2):

Date                  Classification          #
01/01/01              A                      25
01/01/01              B                      35
01/02/01              A                       7
01/03/01              A                       9
01/03/01             No Data                No Data


另一个类似这样的框架:

Date                  Classification          #
01/01/01              A                      25
01/01/01              B                      35
01/02/01              A                       7
01/03/01              A                       9


这基本上意味着按日期和类别(df1)对它们进行分类,然后按日期和类别(df2)对它们进行分类,并排除“无数据”
我做了这个:

length = len(df2)

for i in range length:
    if df1 ['Category'] = "A":
        df1['Date'].map(df.groupby('Date')['Category].sum())


这并没有给予我任何东西,因为我相信这仍然是不完整的。此外,我有一个错误:ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

but5z9lq

but5z9lq1#

您可以将所有#值转换为数值(强制No DataNaN),然后在求和之前groupby DateCategory,用No Data填充NaN并重置索引:

df2 = (pd
    .to_numeric(df1['#'], errors='coerce')
    .groupby([df1['Date'], df1['Category']])
    .sum(min_count=1)
    .fillna('No Data')
    .reset_index()
)

字符串
输出量:

Date Category        #
0  01/01/01        A     25.0
1  01/01/01        B     35.0
2  01/02/01        A      7.0
3  01/03/01        A      9.0
4  01/03/01  No Data  No Data


然后,您可以选择df3作为Category中没有No Data的行:

df3 = df2[df2['Category'] != 'No Data']


输出量:

Date Category     #
0  01/01/01        A  25.0
1  01/01/01        B  35.0
2  01/02/01        A   7.0
3  01/03/01        A   9.0


如果你愿意,你可以将df3['#']恢复为整数:

df3.loc[:, '#'] = df3['#'].astype(int)


输出量:

Date Category   #
0  01/01/01        A  25
1  01/01/01        B  35
2  01/02/01        A   7
3  01/03/01        A   9

txu3uszq

txu3uszq2#

试试这个:

df1.drop(columns=['Name'], inplace=True) # you do not need this column for the grouping
df1['#'] = df1['#'].replace('No Data', 0) # To allow changing the column type to integer
df1['#'] = df1['#'].astype('int') # changing the column type to Integer
df2 = df1.groupby(['Date', 'Category']).sum() Grouping by

字符串
您可以稍后重置索引:df2 = df2.reset_index()

Date    Category    #
0   01/01/01    A      25
1   01/01/01    B      35
2   01/02/01    A       7
3   01/03/01    A       9
4   01/03/01    No Data 0


删除“无数据”:

df2 = df2[df2['Category'] != 'No Data']

gcmastyq

gcmastyq3#

验证码

df2 = pd.to_numeric(df['#'], errors='coerce').fillna(df['#'])\
        .groupby([df['Date'], df['Category']]).sum()\
        .reset_index()\
        .rename(columns={'Category':'Classification'})

字符串
df2:

Date        Classification  #
0   01/01/01    A               25.0
1   01/01/01    B               35.0
2   01/02/01    A               7.0
3   01/03/01    A               9.0
4   01/03/01    No Data         No Data

df2[df2['#'].ne('No Data')]


结果:

Date        Classification  #
0   01/01/01    A               25.0
1   01/01/01    B               35.0
2   01/02/01    A               7.0
3   01/03/01    A               9.0


我创建df2是因为你想要一个像df2这样的DataFrame,最好不要创建df2
生成最终结果而不创建df2的代码。

df.loc[df['#'].ne('No Data'), '#']\
  .astype('int')\
  .groupby([df['Date'], df['Category']]).sum()\
  .reset_index().rename(columns={'Category':'Classification'})


产出:

Date        Classification  #
0   01/01/01    A               25
1   01/01/01    B               35
2   01/02/01    A               7
3   01/03/01    A               9

示例代码

import pandas as pd
data1 = {'Date': ['01/01/01', '01/01/01', '01/01/01', '01/02/01', '01/03/01', '01/03/01'], 
         'Name': ['Vegetables', 'Fruits', 'Meat', 'Vegetables', 'Vegetables', 'No Data'], 
         'Category': ['A', 'A', 'B', 'A', 'A', 'No Data'], 
         '#': ['15', '10', '35', '7', '9', 'No Data']}
df = pd.DataFrame(data1)

s3fp2yjn

s3fp2yjn4#

另一个可能的解决方案:

df1 = (df.groupby(['Date', 'Category'], as_index=False)['#']
       .agg(lambda x: pd.to_numeric(x, errors='coerce')
            .fillna('No Data').sum()))
df2 = df1.where(df1.ne('No Data')).dropna()

字符串
输出量:

(       Date Category        #
 0  01/01/01        A       25
 1  01/01/01        B       35
 2  01/02/01        A        7
 3  01/03/01        A        9
 4  01/03/01  No Data  No Data,
        Date Category   #
 0  01/01/01        A  25
 1  01/01/01        B  35
 2  01/02/01        A   7
 3  01/03/01        A   9)

相关问题