pandas.read_spss 是否将日期时间误读到 unix 中?
Is pandas.read_spss misreading datetime into unix?
我有一个 sav
文件,其中包含 %m/%d/%Y
字符串格式的日期时间列。当我用 pd.read_spss()
读入它时,它似乎没有任何与日期时间相关的参数,它最终以看起来像 unix 时间的方式结束,只是时间将从现在开始几个世纪,具有独特的价值,包括13778726400
、13841884800
等
然而,当我将读取列输入 pd.to_datetime
时,它并没有被解释为我期望的日期,而是在 1970 年的原始 unix 日期之后几秒钟:
pd.to_datetime(df.col)
0 1970-01-01 00:00:13.778726400
1 1970-01-01 00:00:13.841798400
2 1970-01-01 00:00:13.778726400
3 1970-01-01 00:00:13.778035200
4 1970-01-01 00:00:13.841798400
为什么日期时间列以这种奇怪的格式读取,为什么 pd.to_datetime
无法将其转换回来?
(我目前的解决方法只是在SPSS中手动将日期列设置为字符串。然后pyreadstat
/pandas.read_spss
将其读取为字符串没有问题并且pandas.to_dateime
可以转换。 )
日期、时间和日期时间总是作为数字存储在 SPSS 中,然后您添加一种格式进行显示。 SPSS 不断添加新格式,同时删除其他格式。新格式必须手动添加到 pyreadstat 代码,而旧格式保留在代码中以实现向后兼容性。所以问题是你找到了一个新的 Date/datetime/time 格式,它没有在 pyreadstat 中注册。
另一种解决方法是在 SPSS 中打开文件并将其存储为 date/datetime/time,但 pyreadstat 可以识别不同的格式,例如 DATE11、DATETIME20 等(pyreadstat 接受的当前列表是[https://github.com/Roche/pyreadstat/blob/master/pyreadstat/_readstat_parser.pyx#L52-L54])
最好的办法是提交一个 github 问题,描述找到的要添加的新格式。我刚刚添加了一些我在最新的 SPSS documentation 中发现的内容,希望你的问题应该在下一个版本中得到解决(已经在开发人员中可用)。如果没有,请提交带有可重现示例的问题。
SPSS 用于存储日期的数字不是 unix 时间,而是自 1582-10-14(日期)以来的秒数(对于日期时间或时间)或天数(对于日期) Gregorian Calendar 的开始。所以你需要这样的东西来手动计算它:
from datetime import datetime, date, timedelta
origin = date(1582, 10, 14)
myspssvalue = 13778726400
delta = timedelta(seconds=myspssvalue) # or days=myspssvalue if date
python_date = origin + delta
print(python_date)
#datetime.date(2019, 6, 1)
此外,如果您假设此数字是自 1970 年以来的秒数:
>>> datetime.fromtimestamp(13778726400)
datetime.datetime(2406, 8, 19, 2, 0)
pandas 认为您给出的数字是自 1970 年 1 月 1 日以来的纳秒数(它将其转换为 datetime64[ns]),这就是您获得日期的原因非常接近 1970
我有一个 sav
文件,其中包含 %m/%d/%Y
字符串格式的日期时间列。当我用 pd.read_spss()
读入它时,它似乎没有任何与日期时间相关的参数,它最终以看起来像 unix 时间的方式结束,只是时间将从现在开始几个世纪,具有独特的价值,包括13778726400
、13841884800
等
然而,当我将读取列输入 pd.to_datetime
时,它并没有被解释为我期望的日期,而是在 1970 年的原始 unix 日期之后几秒钟:
pd.to_datetime(df.col)
0 1970-01-01 00:00:13.778726400
1 1970-01-01 00:00:13.841798400
2 1970-01-01 00:00:13.778726400
3 1970-01-01 00:00:13.778035200
4 1970-01-01 00:00:13.841798400
为什么日期时间列以这种奇怪的格式读取,为什么 pd.to_datetime
无法将其转换回来?
(我目前的解决方法只是在SPSS中手动将日期列设置为字符串。然后pyreadstat
/pandas.read_spss
将其读取为字符串没有问题并且pandas.to_dateime
可以转换。 )
日期、时间和日期时间总是作为数字存储在 SPSS 中,然后您添加一种格式进行显示。 SPSS 不断添加新格式,同时删除其他格式。新格式必须手动添加到 pyreadstat 代码,而旧格式保留在代码中以实现向后兼容性。所以问题是你找到了一个新的 Date/datetime/time 格式,它没有在 pyreadstat 中注册。
另一种解决方法是在 SPSS 中打开文件并将其存储为 date/datetime/time,但 pyreadstat 可以识别不同的格式,例如 DATE11、DATETIME20 等(pyreadstat 接受的当前列表是[https://github.com/Roche/pyreadstat/blob/master/pyreadstat/_readstat_parser.pyx#L52-L54])
最好的办法是提交一个 github 问题,描述找到的要添加的新格式。我刚刚添加了一些我在最新的 SPSS documentation 中发现的内容,希望你的问题应该在下一个版本中得到解决(已经在开发人员中可用)。如果没有,请提交带有可重现示例的问题。
SPSS 用于存储日期的数字不是 unix 时间,而是自 1582-10-14(日期)以来的秒数(对于日期时间或时间)或天数(对于日期) Gregorian Calendar 的开始。所以你需要这样的东西来手动计算它:
from datetime import datetime, date, timedelta
origin = date(1582, 10, 14)
myspssvalue = 13778726400
delta = timedelta(seconds=myspssvalue) # or days=myspssvalue if date
python_date = origin + delta
print(python_date)
#datetime.date(2019, 6, 1)
此外,如果您假设此数字是自 1970 年以来的秒数:
>>> datetime.fromtimestamp(13778726400)
datetime.datetime(2406, 8, 19, 2, 0)
pandas 认为您给出的数字是自 1970 年 1 月 1 日以来的纳秒数(它将其转换为 datetime64[ns]),这就是您获得日期的原因非常接近 1970