Python pandas到\u csv,然后将\u csv结果读取到numpy.datetime64,由于utc的原因,结果出错

Python pandas到\u csv,然后将\u csv结果读取到numpy.datetime64,由于utc的原因,结果出错,python,csv,pandas,datetime64,Python,Csv,Pandas,Datetime64,简而言之,我的问题是:我试图将我的数据(其中包括np.datetime64值)写入csv,然后将其读回,并且希望我的时间不会改变 正如在许多地方所讨论的,np.datetime64在mem中保留所有二进制和UTC,但从本地时间读取字符串 这里是我的问题的一个小例子,这里是pd.read\u csv(“foo”)从 df.to_csv(“foo”)更改时间的结果: In[184]: num = np.datetime64(datetime.datetime.now()) In[185]: num

简而言之,我的问题是:我试图将我的数据(其中包括np.datetime64值)写入csv,然后将其读回,并且希望我的时间不会改变

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

这里是我的问题的一个小例子,这里是pd.read\u 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
(和往常一样:)

网上有大量的问题和信息,但我已经用谷歌搜索了一段时间,还没有找到解决问题的答案。应该有办法在祖鲁保存数据, 或者假设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仅显示在本地时区中。它已存储在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]这只是一个本地显示。时间如上所述

内部日期时间自epoch起作为ns的
int64
保存

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')

我知道numpy在做什么,这正是你所描述的。我的问题是,pandas parse_dates=['Time']与numpy.datetime64构造函数的工作方式不同,例如:In[46]:pd.read_csv(StringIO(df.to_csv(index=False)),parse_dates=['Time'])。Time[0]==np.datetime64(pd.read_csv(StringIO(df.to_csv(index=False)))。Time[0])Out[46]:False因此,在编写时,答案是使用parse_dates=['Time'])。如果没有它,通过numpy构造函数生成的字符串可能会导致问题。numpy构造函数只是被破坏了,很少会执行您想要的操作。我会尽量避免。
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')