【问题标题】:How to count NA's in aggregate function of a group by using pandas?如何使用 pandas 计算组的聚合函数中的 NA?
【发布时间】:2022-01-14 14:11:19
【问题描述】:

我有一个如下所示的数据框

df = pd.DataFrame(
    {'stud_id' : [101, 101, 101, 101, 
                  101, 101, 101, 101],
     'sub_code' : ['CSE01', 'CSE01', 'CSE01', 
                   'CSE01', 'CSE02', 'CSE02',
                   'CSE02', 'CSE02'],
     'ques_date' : ['13/11/2020', '10/1/2018','11/11/2017', '27/03/2016', 
                '13/05/2010',  '10/11/2008','11/1/2007', '27/02/2006'],
     'resp_date' : [np.nan, '11/1/2018','14/11/2017', '29/03/2016', 
                np.nan, np.nan,np.nan,'28/02/2006'],
     'marks' : [77, 86, 55, 90, 
                65, 90, 80, 67]}
)
df['ques_date'] = pd.to_datetime(df['ques_date'])
df['resp_date'] = pd.to_datetime(df['resp_date'])
df['date_diff'] = (df['resp_date'] - df['ques_date']).dt.days

我想做下面的事情

a) 对于每个 stud_idsub_code 组合,获取平均 date_diff

b) 对于每个stud_idsub_code 组合,获取NA 的平均数。 NAs 表示没有响应。例如:stud_id = 101 AND sub_code = CSE01 组合的 4 条记录中有 1 条 NA,因此 1/4 = 0.25。

我尝试了以下方法,但不确定如何在聚合函数中获取 avg NA

df.groupby(['stud_id','sub_code']).agg(stud_total_records = ('stud_id','count'),
                                            avg_resp_time = ('date_diff','mean'),
                                            lack_resp_pct = (df.groupby(['stud_id','sub_code'])['resp_date'].isna().sum()).reset_index(name='NA_cnt')['NA_cnt']/stud_total_records)

我希望我的输出如下所示

【问题讨论】:

  • datediff 是什么意思? diff 应用于日期时间?
  • 更新了 date_diff 的代码
  • 我不明白为什么avg_resp_time是9和1?为什么不是 12 和 1 或 9 和 0.25?
  • resp_time 对于 subj_id = 101 为 9,因为如果将所有相应的 date_diff 值相加并除以该学生(以及该主题)的总行数,我们只会得到 9.. (36/4 = 9)

标签: python pandas dataframe pandas-groupby series


【解决方案1】:

更新

使用惰性组:

grp = df.groupby(['stud_id', 'sub_code'])

out = grp.agg(stud_total_records = ('stud_id', 'count'),
              avg_resp_time = ('date_diff', 'mean'),
              lack_resp_pct = ('date_diff', lambda x: sum(x.isna()) / df['date_diff'].count())) \
         .reset_index()
print(out)

# Output
   stud_id sub_code  stud_total_records  avg_resp_time  lack_resp_pct
0      101    CSE01                   4           12.0           0.25
1      101    CSE02                   4            1.0           0.75

旧答案 试试:

out = df.groupby(['stud_id','sub_code']).agg(stud_total_records = ('stud_id', 'count'),
                                            avg_resp_time = ('date_diff', 'mean'))

out['lack_resp_pct'] = df[df['date_diff'].isna()].value_counts(['stud_id', 'sub_code'], normalize=True)

输出:

>>> out.reset_index()
   stud_id sub_code  stud_total_records  avg_resp_time  lack_resp_pct
0      101    CSE01                   4           12.0           0.25
1      101    CSE02                   4            1.0           0.75

【讨论】:

  • 我可以看看你为什么会有这个吗? sum(df['date_diff'].isna() 当您可以使用该螺柱和主题组合的总记录数时
  • 谢谢,点赞。但我想答案存在一些问题,它不适用于old 方法
  • 有什么问题? update 是否按预期工作?我可以删除旧的。
  • 我可以知道你为什么使用sum(df['date_diff'].isna())))而不是记录计数吗?。
  • 按习惯 :) 我总是将 sum 与布尔值一起使用,而忘记了 count。你是对的,我更新了我的答案。
猜你喜欢
  • 2015-08-11
  • 1970-01-01
  • 2019-12-08
  • 1970-01-01
  • 2020-07-30
  • 1970-01-01
  • 1970-01-01
  • 2015-01-29
  • 1970-01-01
相关资源
最近更新 更多