对数据帧中的列值进行计数

2024-09-27 00:17:07 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我的数据框

           Date    Name     Attempt   Count
0  2015-01-02    Adam       Yes      
1  2015-01-29    Adam       Yes      
2  2015-02-02    David      No       
3  2015-03-02    David      Yes      
4  2015-03-02    Hardik     Yes       
5  2015-03-02    David      No    

现在我需要计算一个人每月的尝试次数。仅当尝试值为“是”时才要计数,并在“计数”列中插入该值

这是预期的输出

           Date    Name     Attempt    Count
0  2015-01-02    Adam        Yes          2
1  2015-01-29    Adam        Yes          2
2  2015-02-02    David       No           0
3  2015-03-02    David       Yes          1
4  2015-03-02    Hardik      Yes          1 
5  2015-03-02    David       No           1

Tags: 数据nonamedatecount次数yes计数
2条回答

您需要将日期和姓名按月份频率分组,并计算有多少次尝试是“是”。添加一点临时助手信息作为唯一月份:

df['year_x_month'] = df['date'].apply(lambda x: x.year * x.month)
res = df[df["Attempt"].eq("Yes")]
                      .groupby(['year_x_month', 'Name'])['Attempt']
                      .count()

res看起来像这样(多索引为('year\u x\u month','Name'):

year_x_month  Name  
2015          Adam      2
6045          David     1
              Hardik    1
Name: Attempt, dtype: int64

现在,使用年/月和人名的唯一组合图,分配每人和每月的尝试次数:

my_map = dict(zip(res.index, res.values))
df['Counts'] = pd.Series(zip(df['year_x_month'], df['Name'])).map(my_map))
del df['year_x_month']

输出:

        date    Name Attempt  Counts
0 2015-01-02    Adam     Yes     2.0
1 2015-01-29    Adam     Yes     2.0
2 2015-02-02   David      No     NaN
3 2015-03-02   David     Yes     1.0
4 2015-03-02  Hardik     Yes     1.0
5 2015-03-02   David      No     1.0

注意:删除了以前有缺陷的实施

在看到@ThePyGuy给出的漂亮答案后。我对检查他和我的建议的性能很感兴趣(我希望没有一个比另一个更“正确”),并发现他的建议需要4.53毫秒,我的建议需要3.97毫秒。请注意,这些统计数据是针对这个小数据集的。性能可能会随着数据帧的大小而奇怪地扩展

如果尚未将Date列转换为datetime类型,则将临时列指定为month,从Date列提取月份值

然后为Attempt列过滤出具有Yes值的行,并按monthName列对其进行分组,然后调用size获取计数,最后调用to_frame传递count作为列名来创建一个数据帧,并将其与left合并并传递on参数的公共键,然后fillna(0),删除月份列,并将计数列转换为整数类型

df['Date'] = pd.to_datetime(df['Date'])
df['month']=df['Date'].dt.month
(df.merge(df[df['Attempt'].eq('Yes')]
             .groupby(['month', 'Name'])
             .size()
             .to_frame('count'), 
        how='left', 
        on=['month', 'Name']
        ).fillna(0).drop(columns='month').astype({'count':int})
)
        Date    Name Attempt  count
0 2015-01-02    Adam     Yes      2
1 2015-01-29    Adam     Yes      2
2 2015-02-02   David      No      0
3 2015-03-02   David     Yes      1
4 2015-03-02  Hardik     Yes      1
5 2015-03-02   David      No      1

相关问题 更多 >

    热门问题