Python:如何根据日期时间获取值的计数

Posted

技术标签:

【中文标题】Python:如何根据日期时间获取值的计数【英文标题】:Python: How to get count of values based on datetime 【发布时间】:2021-01-08 14:36:26 【问题描述】:

我编写了以下代码,它创建了两个数据帧nqcmntnq 包含UserId 和相应的徽章获得时间datecmnt 包含@ 987654327@和用户发表评论的时间CreationDate。 我想计算获得徽章 1 周前后所有天的 cmets 数量,以便我可以从中创建时间序列线图。

以下代码执行相同的操作,但会产生 KeyError。请提供为所有用户执行此操作的代码。

nq

 UserId |   date 
     1      2009-10-17 17:38:32.590
     2      2009-10-19 00:37:23.067
     3      2009-10-20 08:37:14.143
     4      2009-10-21 18:07:51.247
     5      2009-10-22 21:25:24.483

cmnt

OwnerUserId | CreationDate
1             2009-10-16 17:38:32.590
1             2009-10-18 17:38:32.590
2             2009-10-18 00:37:23.067
2             2009-10-17 00:37:23.067
2             2009-10-20 00:37:23.067
3             2009-10-19 08:37:14.143
4             2009-10-20 18:07:51.247
5             2009-10-21 21:25:24.483

代码

 nq.date = pd.to_datetime(nq.date)
 cmnt.CreationDate = pd.to_datetime(cmnt.CreationDate)

 count= []
   
 for j in range(len(nq)): 
      for i in range(-7,8):
        
          check_date = nq.date.iloc[j] + timedelta(days=i)
          
          count = cmnt.loc[(cmnt.OwnerUserId == nq.UserId.iloc[j]) & (cmnt.CreationDate == check_date)].shape[0]
          nq.iloc[j].append(nq[i]:count)

预期输出

UserId     |   date                 |-7|-6|-5|-4|-3|-2|-1|0 |1 |2 |3 |4 |5 |6 |7
     1      2009-10-17 17:38:32.590 |0 |0 |0 |0 |0 |0 |1 |0 |1 |0 |0 |0 |0 |0 |0  
     2      2009-10-19 00:37:23.067 |0 |0 |0 |0 |0 |1 |1 |0 |1 |0 |0 |0 |0 |0 |0    
     3      2009-10-20 08:37:14.143 |0 |0 |0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 
     4      2009-10-21 18:07:51.247 |0 |0 |0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 
     5      2009-10-22 21:25:24.483 |0 |0 |0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 

这里的列-1表示获得徽章前1天发表的评论,1表示获得徽章后一天发表的评论,依此类推。

注意 可以有一种完全替代的方法来做到这一点。我的主要目标是绘制一个时间序列线图,显示用户在获得徽章之前和之后所做的 cmets 数量。

【问题讨论】:

【参考方案1】:

您可能想要一个交叉合并、过滤器,然后是一个crosstab

# merge the two dataframes
merged = (nq.merge(cmnt, left_on='UserId', 
         right_on='OwnerUserId',
         how='left')
)

# extract the date difference between `date` and `CreationDate`
merged['date_diff'] = merged['date'].dt.normalize() - merged['CreationDate'].dt.normalize()
merged['date_diff'] = (merged['date_diff'] / pd.to_timedelta('1D')).astype(int)

# filter the comments within the range
merged = merged[merged['date_diff'].between(-7,7)]

# crosstab
pd.crosstab([merged['UserId'],merged['date']], merged['date_diff'])

输出:

date_diff                       -1   1   2
UserId date                               
1      2009-10-17 17:38:32.590   1   1   0
2      2009-10-19 00:37:23.067   1   1   1
3      2009-10-20 08:37:14.143   0   1   0
4      2009-10-21 18:07:51.247   0   1   0
5      2009-10-22 21:25:24.483   0   1   0

【讨论】:

这给出了正确的输出。您能否在您的解决方案中添加如何将此交叉表转换为数据框? 那个交叉表命令返回一个数据框。只需将其分配给某些东西,例如out = pd.crosstab(...). 是的,但我希望它有以下列 ['UserId', "date", -7, -6, ...0....,6, 7] 我可以像普通 DataFrame 列一样访问。但现在列是Int64Index([-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7], dtype='int64', name='date_diff')。所以现在命令 df['UserId'] 给出错误,因为 'UserId' 不是 df 的列。 (df = pd.crosstab(...)) reset_index()pd.crosstab() 对于某些输入,我收到此错误ValueError: Cannot convert non-finite values (NA or inf) to integer。如何解决这个问题?

以上是关于Python:如何根据日期时间获取值的计数的主要内容,如果未能解决你的问题,请参考以下文章

如何在日期时间 Python 中获取值计数

如何获取日期的最大计数和相应的 hour_id?

SQL根据连续日期获取值的变化

如何根据可用性表计算下一天/同一天?

如何根据特定日期获取最后修改的文件并导入python脚本[重复]

查询滚动日期范围和国家/地区中不同值的计数