pandas to_csv 然后 read_csv 导致 numpy.datetime64 由于 utc 而混乱

pandas to_csv and then read_csv results to numpy.datetime64 messed up due to utc

我的问题简而言之:我正在尝试将我的数据(包含 np.datetime64 值等)写入 csv,然后将它们读回,并希望我的时间不改变...

正如在许多地方讨论的那样,np.datetime64 在内存中保留所有二进制和 UTC,但从本地时间读取字符串。

这是我的问题的一个简单示例,这里 pd.read_csv("foo") 保存自 df.to_csv("foo") 改变时间的结果:

In[184]: num = np.datetime64(datetime.datetime.now())
In[185]: num
Out[181]: numpy.datetime64('2015-10-28T19:19:42.408000+0100')
In[186]: df = pd.DataFrame({"Time":[num]})
In[187]: df
Out[183]: 
                        Time
0 2015-10-28 18:19:42.408000
In[188]: df.to_csv("foo")
In[189]: df2=pd.read_csv("foo")
In[190]: df2
Out[186]: 
   Unnamed: 0                        Time
0           0  2015-10-28 18:19:42.408000
In[191]: np.datetime64(df2.Time[0])
Out[187]: numpy.datetime64('2015-10-28T18:19:42.408000+0100')
In[192]: num == np.datetime64(df2.Time[0])
Out[188]: False

(像往常一样:)

import numpy as np
improt pandas as pd

网络上有很多问题和大量信息,但我已经谷歌搜索了一段时间,但未能找到有关如何克服这个问题的答案。应该有一些方法可以保存祖鲁语中的数据, 或阅读他们假设 UTC,但没有找到任何最好(或什至好?)的方法。 我可以

In[193]: num == np.datetime64(df2.Time[0]+"Z")
Out[189]: True

但在我看来,就实践、可移植性和效率而言,这真的很糟糕……(再加上使用默认保存和读取时会把事情搞得一团糟)

numpy 构造函数完全损坏,很少会执行您想要的操作。我会简单地避免。改用:

pd.read_csv(StringIO(df.to_csv(index=False)),parse_dates=['Time'])

np.datetime64 只是 display 在本地时区。它已经存储在 UTC 中。

In [42]: num = np.datetime64(datetime.datetime.now())

In [43]: num
Out[43]: numpy.datetime64('2015-10-28T10:02:22.298130-0400')

In [44]: df = pd.DataFrame({"Time":[num]})

In [45]: df
Out[45]: 
                        Time
0 2015-10-28 14:02:22.298130

In [46]: pd.read_csv(StringIO(df.to_csv(index=False)),parse_dates=['Time'])            
Out[46]: 
                        Time
0 2015-10-28 14:02:22.298130

In [47]: pd.read_csv(StringIO(df.to_csv(index=False)),parse_dates=['Time']).Time.values
Out[47]: array(['2015-10-28T10:02:22.298130000-0400'], dtype='datetime64[ns]')

[47] 只是一个本地显示。时间如上

自纪元以来,内部日期时间保存为 int64 ns。

In [7]: Timestamp('2015-10-28 14:02:22.298130')       
Out[7]: Timestamp('2015-10-28 14:02:22.298130')

In [8]: Timestamp('2015-10-28 14:02:22.298130').value
Out[8]: 1446040942298130000

In [9]: np.array([1446040942298130000],dtype='M8[ns]')
Out[9]: array(['2015-10-28T10:02:22.298130000-0400'], dtype='datetime64[ns]')

In [10]: Timestamp(np.array([1446040942298130000],dtype='M8[ns]').view('i8').item())
Out[10]: Timestamp('2015-10-28 14:02:22.298130')