Pandas日期时间转换为Unix时间戳秒数。

66

pandas.to_datetime的官方文档中我们可以得知,

unit:字符串,默认为“ns”

参数的单位(D、s、ms、us、ns)表示单位的整数或浮点数。这将基于原点。例如,当unit='ms'和origin='unix'(默认值)时,这将计算到Unix纪元开始的毫秒数。

所以当我尝试像这样操作时,

import pandas as pd
df = pd.DataFrame({'time': [pd.to_datetime('2019-01-15 13:25:43')]})
df_unix_sec = pd.to_datetime(df['time'], unit='ms', origin='unix')
print(df)
print(df_unix_sec)

                 time
0   2019-01-15 13:25:43
0   2019-01-15 13:25:43
Name: time, dtype: datetime64[ns]

对于后者,输出没有改变。每次都显示日期时间值而不是第二个开始的毫秒数。为什么会这样?我有遗漏什么吗?

5个回答

126

我认为你误解了参数的作用。 origin='unix' 的目的是将整数时间戳转换为datetime,而不是相反。

pd.to_datetime(1.547559e+09, unit='s', origin='unix') 
# Timestamp('2019-01-15 13:30:00')

以下是一些选项:

选项1:整除

相反,你可以通过将时间戳转换为整数(以获取纳秒)并除以109来获取时间戳。

pd.to_datetime(['2019-01-15 13:30:00']).astype(int) / 10**9
# Float64Index([1547559000.0], dtype='float64')

优点:

  • 超快速度

缺点:

  • 假设了pandas内部如何存储日期数据

选项2:由pandas推荐

Pandas文档推荐使用以下方法:

# create test data
dates = pd.to_datetime(['2019-01-15 13:30:00'])

# calculate unix datetime
(dates - pd.Timestamp("1970-01-01")) // pd.Timedelta('1s')

[out]:
Int64Index([1547559000], dtype='int64')

优点:

  • 符合惯用语,由库推荐

缺点:

  • 笨重
  • 性能不如整数除法

选项 3:pd.Timestamp

如果你只有一个日期字符串,可以使用 pd.Timestamp,如其他答案所示:

pd.Timestamp('2019-01-15 13:30:00').timestamp()
# 1547559000.0

如果你必须强制转换多个日期时间(只能使用pd.to_datetime),你可以进行初始化并映射:

pd.to_datetime(['2019-01-15 13:30:00']).map(pd.Timestamp.timestamp)
# Float64Index([1547559000.0], dtype='float64')

优点:

  • 对于单个日期时间字符串来说,是最佳的方法
  • 易于记忆

缺点:

  • 与整数除法相比性能不如优秀

请注意,Pandas现在建议使用.view()替代方法1中的.astype()。该方法也适用于(带时区的)DateTimeIndex数组,除非在该时间跨度内开始或结束夏令时。在这种情况下,会出现TypeError: Cannot change data-type for object array.将其转换为UTC可以解决此问题。 - AstroFloyd

28
您可以使用 timestamp() 方法,它将以浮点数的形式返回 POSIX 时间戳:
pd.Timestamp('2021-04-01').timestamp()

[Out]:
1617235200.0

pd.Timestamp('2021-04-01 00:02:35.234').timestamp()

[Out]:
1617235355.234

3

pandas Timestampvalue属性保存了Unix纪元时间。这个值以纳秒为单位。所以,你可以通过除以1e3或1e6来转换为毫秒或微秒。请查看下面的代码。

import pandas as pd
date_1 = pd.to_datetime('2020-07-18 18:50:00')
print(date_1.value) 

1
当你计算两个日期时间之间的差值时,默认情况下,差值的数据类型为timedelta64[ns](括号中的ns)。通过将输出转换为新的timedelta64对象并将[ns]更改为[ms][s][m]等,可将差值转换为毫秒、秒、分钟等。
例如,要查找自Unix纪元以来经过的秒数,请减去日期时间并更改数据类型。
df_unix_sec = (df['time'] - pd.Timestamp('1970-01-01')).astype('timedelta64[s]')

注意:通常情况下,这些差异是非常大的数字,因此如果您想将它们转换为整数,请使用 astype('int64')(而不是 astype(int))。

df_unix_sec = (df['time'] - pd.Timestamp('1970-01-01')).astype('timedelta64[s]').astype('int64')

针对OP的示例,这将产生以下结果:
0    1547472343
Name: time, dtype: int64

-2

如果您从数据框中访问特定的datetime64对象,那么很有可能pandas会返回一个Timestamp对象,这实际上是pandas存储datetime64对象的方式。

您可以使用pd.Timestamp.to_datetime64()方法将pd.Timestamp对象转换为具有ns精度的numpy.datetime64对象。


欢迎来到SO!感谢您抽出时间回答这个问题。请仔细阅读原帖的问题。您的解决方案是否比已接受的答案更好/不同? - above_c_level

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接