【问题标题】:How to correctly use pandas agg function when running groupby on a column of type timestamp/datetime/datetime64?在时间戳/日期时间/日期时间64类型的列上运行groupby时如何正确使用pandas agg函数?
【发布时间】:2015-08-10 21:35:16
【问题描述】:

我试图理解为什么直接在一个组上调用 count() 会返回正确的答案(在本例中,该组中有 2 行),但通过 agg() 函数中的 lambda 调用 count 会返回纪元(“1970-01-01 00:00:00.000000002”)。

# Using groupby(lambda x: True) in the code below just as an illustrative example.
# It will always create a single group.
x = DataFrame({'time': [np.datetime64('2005-02-25'), np.datetime64('2006-03-30')]}).groupby(lambda x: True)

display(x.count())
>>time
>>True  2

display(x.agg(lambda x: x.count()))
>>time
>>True  1970-01-01 00:00:00.000000002

这可能是熊猫的一个错误吗?我在用 熊猫版本:0.16.1 IPython 版本:3.1.0 numpy 版本:1.9.2

无论我使用标准 python 日期时间、np.datetime64 还是熊猫时间戳,我都会得到相同的结果。

编辑(根据@jeff 接受的答案,看起来我可能需要在应用不返回日期时间类型的聚合函数之前强制转换为 dtype 对象):

dt = [datetime.datetime(2012, 5, 1)] * 2
x = DataFrame({'time': dt})
x['time2'] = x['time'].astype(object)
display(x)
y = x.groupby(lambda x: True)
y.agg(lambda x: x.count())

>>time  time2
>>True  1970-01-01 00:00:00.000000002   2

【问题讨论】:

    标签: python datetime pandas count aggregate


    【解决方案1】:

    这里的 x 是上面的原始帧(不是你的 groupby)。传递 UDF,例如lambda,在每个系列上调用它。所以这是函数的结果。

    In [35]: x.count()
    Out[35]: 
    time    2
    dtype: int64
    

    然后强制转换为 Series 的原始 dtype。所以结果是:

    In [36]: Timestamp(2)
    Out[36]: Timestamp('1970-01-01 00:00:00.000000002')
    

    这正是您所看到的。对原始 dtype 进行强制的目的是尽可能保留它。不这样做对 groupby 结果会更神奇。

    【讨论】:

    • 谢谢,有道理。如果我将 datetime64 强制为 dtype 对象,那么它会按预期聚合。这是处理这个问题最合理的方法吗?据推测,通过以这种方式强制转换为对象,我会失去一些性能,但我不确定有什么好的选择。
    • 好吧,你在做什么聚合?来自datetime64[ns]的groupby。我想不出很多我们还没有定义的东西(或者你会首先在框架上操作并做一些事情)。
    • 我正在检查有缺失值的行,但没有相应的函数,所以我必须这样做 (len - count()),所以我将函数列表传递给 agg()。例如。 x.groupby(lambda x: True).agg(['count', len])。如果我将列类型保留为日期时间,则 len 函数的输出将被强制为日期时间。
    • 另外,我可以在返回之前将自定义聚合函数的输出转换为浮点数(此时 pandas 不会尝试将它们强制转换回日期时间)
    • df.isnull() 不适合你吗?对所有内容进行分组并进行这样的计数是非常奇怪的。
    猜你喜欢
    • 2020-02-12
    • 2017-11-19
    • 2016-10-05
    • 2013-06-16
    • 1970-01-01
    • 2018-07-09
    • 1970-01-01
    • 2021-02-25
    • 1970-01-01
    相关资源
    最近更新 更多