【问题标题】:select data based on datetime in pandas dataframe根据熊猫数据框中的日期时间选择数据
【发布时间】:2020-03-27 14:43:49
【问题描述】:

我正在尝试创建某种“功能选择”,让用户可以灵活地创建配置以选择 pandas 数据框中的数据。然而,我遇到了一些令我困惑的问题。

下面是一个简化的例子:

>>> import pandas as pd
>>> df = pd.DataFrame({'date': pd.date_range(start='2020-01-01', periods=4), 'val': [1, 2, 3, 4]})
>>> df
        date  val
0 2020-01-01    1
1 2020-01-02    2
2 2020-01-03    3
3 2020-01-04    4

问题 1: 为什么在不同的列上应用函数会得到不同的结果?

>>> import datetime
>>> bydatetime = lambda x : x == datetime.date(2020, 1, 1)
>>> bydatetime(df['date'])
0    False
1    False
2    False
3    False
Name: date, dtype: bool
>>> df['date'].apply(bydatetime) # why does this one work?
0     True
1    False
2    False
3    False
Name: date, dtype: bool

但是,如果我使用 numpy 的 datetime64 或 pandas 的 Timestamp 类型来创建 lambda 函数,它会起作用。

>>> import numpy as np
>>> bynpdatetime = lambda x : x == np.datetime64('2020-01-01')
>>> bynpdatetime(df['date'])
0     True
1    False
2    False
3    False
Name: date, dtype: bool
>>> df['date'].apply(bynpdatetime)
0     True
1    False
2    False
3    False
Name: date, dtype: bool
>>> bypdtimestamp = lambda x : x == pd.Timestamp('2020-01-01')
>>> bypdtimestamp(df['date'])
0     True
1    False
2    False
3    False
Name: date, dtype: bool
>>> df['date'].apply(bypdtimestamp)
0     True
1    False
2    False
3    False
Name: date, dtype: bool

所以我恢复使用以下简单选择,但使用 datetime.date 不起作用。如果datetime.date 不起作用,为什么df['date'].apply(bydatetime) 会起作用?

>>> df[df['date'] == datetime.date(2020, 1, 1)]
Empty DataFrame
Columns: [date, val]
Index: []
>>> df[df['date'] == np.datetime64('2020-01-01')]
        date  val
0 2020-01-01    1
>>> df[df['date'] == pd.Timestamp('2020-01-01')]
        date  val
0 2020-01-01    1

最后但同样重要的是,为什么选择一个单元格时,DataFrame 中date 列的类型为datetime64 而Timestamp?它们之间究竟有什么区别?

>>> df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype         
---  ------  --------------  -----         
 0   date    4 non-null      datetime64[ns]
 1   val     4 non-null      int64         
dtypes: datetime64[ns](1), int64(1)
memory usage: 192.0 bytes
>>>
>>> df['date'][0]
Timestamp('2020-01-01 00:00:00')

我确信这里有一些我不理解的基本内容。非常感谢您提出的任何建设性意见。

【问题讨论】:

    标签: python pandas datetime


    【解决方案1】:

    幸运的是,我有一个旧版本的 pandas (0.25),当您执行 bynpdatetime(df['date']) 时会收到警告,这正是您看到这种行为的原因。 There was a bit of back and forth on how to handle this 所以看到这种行为将是高度特定于版本的:

    FutureWarning:将日期时间系列与“datetime.date”进行比较。 目前,“datetime.date”被强制转换为日期时间。在将来 pandas 不会强制,并且 ' 值不会比较等于 'datetime.date'。 要保留当前行为,请将 'datetime.date' 到带有 'pd.Timestamp' 的日期时间。

    Datetime functionality in pandas 建立在 np.datetime64 和 np.timedelta64 dtypes 之上。 您不应该使用 datetime 模块,因为他们做出了与标准库不一致的某些选择。所有的意外行为都是因为这个。


    回答另一个不相关的问题。 datetime64 就像数组类型或概念。该数组(在本例中为pd.Series)将由标量timedelta64 对象组成。这在documentation 中有解释

    【讨论】:

    • @SergeBallesta 这绝对是开始使用 pandas 时最大的障碍之一,我希望他们能更明确地说明,并可能添加有关使用 datetime 对象的警告。大多数情况下,这些事情都会随着时区出现,但随着这样的更新,列表会继续变长。
    猜你喜欢
    • 1970-01-01
    • 2021-12-14
    • 2016-12-08
    • 2012-10-24
    • 2016-05-08
    • 2020-05-05
    • 2013-06-09
    • 2015-10-30
    • 1970-01-01
    相关资源
    最近更新 更多