【问题标题】:pandas fillna datetime column with timezone now现在带有时区的熊猫填充日期时间列
【发布时间】:2017-07-04 10:20:10
【问题描述】:

我有一个带有 None 值的 pandas 日期时间列,我想在特定时区用 datetime.now() 填充。

这是我的 MWE 数据框:

df = pd.DataFrame([
    {'end': "2017-07-01 12:00:00"},
    {'end': "2017-07-02 18:13:00"},
    {'end': None},
    {'end': "2017-07-04 10:45:00"}
])

如果我填写fillna:

pd.to_datetime(df['end']).fillna(datetime.now())

结果是一个具有预期 dtype 的系列:datetime64[ns]。但是当我指定时区时,例如:

pd.to_datetime(df['end']).fillna(
    datetime.now(pytz.timezone('US/Pacific')))

这将返回一个数据类型为:object的系列

【问题讨论】:

  • 期望的输出是什么?您是否需要列中的混合时区? UTC 与 US/Pacific ?
  • 请注意,这样做会将所有时间戳转换为该时区,最终结果是正确的,如果您查看任何特定元素值,它就是带有所需时区信息的时间戳。只是numpy没有支持这个的dtype,但是dtype是时间戳,支持数值运算

标签: pandas datetime python-3.6


【解决方案1】:

看来您需要在fillna 中将date 转换为to_datetime

df['end'] = pd.to_datetime(df['end'])
df['end'] = df['end'].fillna(pd.to_datetime(pd.datetime.now(pytz.timezone('US/Pacific'))))
print (df)
                                end
0               2017-07-01 12:00:00
1               2017-07-02 18:13:00
2  2017-07-04 03:35:08.499418-07:00
3               2017-07-04 10:45:00

print (df['end'].apply(type))
0    <class 'pandas._libs.tslib.Timestamp'>
1    <class 'pandas._libs.tslib.Timestamp'>
2    <class 'pandas._libs.tslib.Timestamp'>
3    <class 'pandas._libs.tslib.Timestamp'>
Name: end, dtype: object

dtype 仍然不是datetime64

print (df['end'].dtype)
object

我认为解决方案是将参数utc 传递给to_datetime

utc:布尔值,默认无

如果为 True,则返回 UTC DatetimeIndex(也转换任何 tz 感知 datetime.datetime 对象)。

df['end'] = df['end'].fillna(pd.datetime.now(pytz.timezone('US/Pacific')))
df['end'] = pd.to_datetime(df['end'], utc=True)

#print (df)

print (df['end'].apply(type))
0    <class 'pandas._libs.tslib.Timestamp'>
1    <class 'pandas._libs.tslib.Timestamp'>
2    <class 'pandas._libs.tslib.Timestamp'>
3    <class 'pandas._libs.tslib.Timestamp'>
Name: end, dtype: object

print (df['end'].dtypes)
datetime64[ns]

来自comment of OP的最终解决方案:

df['end'] = pd.to_datetime(df['end']).dt.tz_localize('US/Pacific')
df['end'] = df['end'].fillna(pd.datetime.now(pytz.timezone('US/Pacific')))

print (df.end.dtype)
datetime64[ns, US/Pacific]

【讨论】:

  • 现在返回 UTC 而不是指定时区
  • 是的,完全正确。如果需要 datetime64 则问题有 datetime64 dtypes 如果某些日期包含时区而另一个不包含。如果所有日期都有时区或没有时区信息,它会完美运行。
  • 我也发现了这个warning - Warning It is incorrect to pass a timezone directly into the datetime.datetime constructor (e.g., datetime.datetime(2011, 1, 1, tz=timezone('US/Eastern')). Instead, the datetime needs to be localized using the the localize method on the timezone.
  • 谢谢!通过使用时区定义to_datetime 解决:df['end'] = pd.to_datetime(df['end']).dt.tz_localize('US/Pacific') 然后.fillna
  • 大佬,我加个回答。
猜你喜欢
  • 1970-01-01
  • 2013-09-25
  • 2018-08-17
  • 2020-05-15
  • 1970-01-01
  • 2022-01-07
  • 2020-10-19
  • 2018-04-24
  • 2017-10-18
相关资源
最近更新 更多