【问题标题】:Python Pandas Dataframe Conditional Count with Datetime Comparison Condition具有日期时间比较条件的 Python Pandas Dataframe 条件计数
【发布时间】:2021-05-06 17:01:02
【问题描述】:

背景

我有两个数据框。第一个,df_player_snapshot_master,有个人扑克玩家在锦标赛中不同时间的快照数据,如下所示:

    snapshotDateTime            playerID    deactivationRecord
0   2021-05-06 09:28:24.987995  1679613     False
1   2021-05-06 09:28:24.987995  2660567     False
2   2021-05-06 09:28:24.987995  2668394     False
3   2021-05-06 09:28:24.987995  2280604     False
4   2021-05-06 09:28:24.987995  2018271     False

第二个数据框df_tournament_summary_master通过快照在锦标赛级别汇总了这些数据,如下所示:

    intervalStartDateTime       intervalEndDateTime         playersDeactivatedThisInterval
0   2021-05-06 09:28:24.987995  2021-05-06 09:28:38.605930  NaN
1   2021-05-06 09:28:38.605930  2021-05-06 09:28:47.860595  NaN
2   2021-05-06 09:28:47.860595  2021-05-06 09:28:57.187734  NaN
3   2021-05-06 09:28:57.187734  2021-05-06 09:29:07.187734  NaN

我的目标是通过计算df_player_snapshot_master 中的记录数来填充df_tournament_summary_master['playersDeactivatedThisInterval'],其中df_player_snapshot_master['snapshotDateTime'] 等于df_tournament_summary_master['intervalStartDateTime']df_player_snapshot_master['deactivationRecord']True。因此,本质上是具有多个条件的两个数据帧之间的 COUNTIFS 练习。

我的尝试

我将this post 中的解决方案翻译成我的情况,导致了这个代码:

tournament_info = df_tournament_summary_master[['intervalStartDateTime']].values

deacs = []

for iSDT in tournament_info:
    deacs.append(len(df_player_snapshot_master[(df_player_snapshot_master['snapshotDateTime']==iSDT) &
                                  (df_player_snapshot_master['deactivationRecord']==True)])
                          )

df_tournament_summary_master['playersDeactivatedThisInterval'] = deacs

但它一直抛出错误:

ValueError: ('Lengths must match to compare', (332,), (1,))

我为我的代码建模的帖子确实提到了需要转换为日期时间,这似乎是问题所在,但是当我检查我的两个数据帧/系列的类型时,它们似乎都已经是日期时间了:

In:
display(tournament_info)

Out:
array([['2021-05-06T09:28:24.987995000'],
       ['2021-05-06T09:28:38.605930000'],
       ['2021-05-06T09:28:47.860595000'],
       ['2021-05-06T09:28:57.187734000']], dtype='datetime64[ns]')

In:
df_player_snapshot_master.dtypes

Out:
snapshotDateTime           datetime64[ns]
playerID                           object
deactivationRecord                   bool
dtype: object

当然,我看过其他通过比较日期来处理过滤数据帧的帖子,它们似乎都使用了与我想使用的 for 循环不同的解决方案,所以我不知道如何重新调整用途并调整他们的建议。

问题

  1. 是什么导致了我得到的 ValueError?
  2. 如何使用日期比较条件向df_tournament_summary_master['playersDeactivatedThisInterval'] 填充条件计数?

【问题讨论】:

    标签: python pandas dataframe countif python-datetime


    【解决方案1】:

    您可以通过在snapshotDateTime 上的groupby 之后计算deactivationRecordsum 来做到这一点,然后合并数据帧。您的示例数据的结果并不那么令人兴奋,但它应该可以工作:

    time_groups = df_player_snapshot_master.groupby('snapshotDateTime')['deactivationRecord'].sum()
    df = pd.merge(df_tournament_summary_master, time_groups, how='left', left_on=['intervalStartDateTime'], right_on=['snapshotDateTime'])
    df = df.drop(['playersDeactivatedThisInterval'], axis = 1).rename(columns={"deactivationRecord": "playersDeactivatedThisInterval"})
    

    结果:

    intervalStartDateTime intervalEndDateTime playersDeactivatedThisInterval
    0 2021-05-06 09:28:24.987995 2021-05-06 09:28:38.605930 0
    1 2021-05-06 09:28:38.605930 2021-05-06 09:28:47.860595 nan
    2 2021-05-06 09:28:47.860595 2021-05-06 09:28:57.187734 nan
    3 2021-05-06 09:28:57.187734 2021-05-06 09:29:07.187734 nan

    【讨论】:

    • 感谢您的回答。这确实解决了问题。我有其他类似的应用程序,虽然我正在执行条件计数,但我不确定这如何推广到一个条件、三个条件或条件具有非布尔数据类型时。这就是为什么我引用的链接中的for 循环格式如此吸引人的原因。这是否容易推广到其他类似的场景?
    猜你喜欢
    • 1970-01-01
    • 2023-02-07
    • 1970-01-01
    • 2021-08-21
    • 1970-01-01
    • 2013-03-17
    • 2016-12-09
    • 2022-01-06
    • 2011-09-10
    相关资源
    最近更新 更多