熊猫:按组计算唯一的日期时间值会给出奇怪的值

Posted

技术标签:

【中文标题】熊猫:按组计算唯一的日期时间值会给出奇怪的值【英文标题】:Pandas: counting unique datetime values in group by gives weird values 【发布时间】:2017-05-26 14:47:01 【问题描述】:

所以我得到了这个 DataFrame,它的构建方式使得对于列 id 等于 2,我们在列 nummy_date 中有两个不同的值:

import pandas as pd

a = pd.DataFrame('id': [1, 2, 3, 2], 
                  'my_date': [datetime(2017, 1, i) for i in range(1, 4)] + [datetime(2017, 1, 1)],
                  'num': [2, 3, 1, 4]
            )

为方便起见,这是可视化的 DataFrame:

如果我想计算每个 id 的唯一值的数量,我会这样做

grouped_a = a.groupby('id').agg('my_date': pd.Series.nunique, 
                                 'num': pd.Series.nunique).reset_index()
grouped_a.columns = ['id', 'num_unique_num', 'num_unique_my_date']

这给出了这个奇怪的 (?) 结果:

看起来datetime(在 Pandas 中转换为 datetime64[ns])类型上的唯一值计数不起作用?

【问题讨论】:

【参考方案1】:

这是错误,请参阅github 14423。

但是你可以使用SeriesGroupBy.nunique,效果很好:

grouped_a = a.groupby('id').agg('my_date': 'nunique', 
                                 'num': 'nunique').reset_index()
grouped_a.columns = ['id', 'num_unique_num', 'num_unique_my_date']
print (grouped_a)
   id  num_unique_num  num_unique_my_date
0   1               1                   1
1   2               2                   2
2   3               1                   1

如果DataFrame 只有3 列,您可以使用:

grouped_a = a.groupby('id').agg(['nunique']).reset_index()
grouped_a.columns = ['id', 'num_unique_num', 'num_unique_my_date']
print (grouped_a)
   id  num_unique_num  num_unique_my_date
0   1               1                   1
1   2               2                   2
2   3               1                   1

【讨论】:

太棒了!也碰巧知道Series.nunique 有什么问题吗?我以为普通的'nunique' 会这么叫。 jezrael 打败了我。但这很奇怪!看起来熊猫在传递函数时试图强加列 dtype。但是当您使用内置的nunique 时,它就知道该怎么做了。 对不起,我不知道为什么它不能很好地与pd.Series.nunique一起工作,但请尝试找到它。 但可能有一些错误。 一种可能的解决方法是键入 cast my_date 到字符串 dtype 以按原样使用语法。在 datetime 列上执行数值聚合时,感觉这个问题仍然存在。

以上是关于熊猫:按组计算唯一的日期时间值会给出奇怪的值的主要内容,如果未能解决你的问题,请参考以下文章

在R中按组计算日期之间的差异

熊猫以时间为索引获取特定日期的行数

计算接下来 30 天的隔天的 TimeInMillis 值会给我在 Kotlin 中的错误日期

熊猫中按组的唯一性索引

将熊猫系列时间戳转换为唯一日期列表

熊猫从不统一的日期列表中查找一年前的日期