0

我正在从 Matlab 迁移...在 Windows 10 中使用 Jupyter Lab。

假设我有一个时间序列,其中包含一组 datetime64 和一些其他数据

t = np.arange('2010-09-01','2010-09-02', dtype='datetime64[6h]')

d = np.linspace(0,1,len(t))

我想合并两者以保存在另一个笔记本中继续工作(我知道还有其他方法可以做到这一点!)。首先,我将它们转换为列数组

t_col = t.reshape(-1,1)
d_col = d.reshape(-1,1)

并合并

m = np.c_[t_col, d_col]

并得到

TypeError                                 Traceback (most recent call last)
<ipython-input-28-5bbb5e23249f> in <module>
----> 1 m = np.c_[t_col, d_col]

c:\Python37_32\lib\site-packages\numpy\lib\index_tricks.py in __getitem__(self, key)
    333                 objs[k] = objs[k].astype(final_dtype)
    334 
--> 335         res = self.concatenate(tuple(objs), axis=axis)
    336 
    337         if matrix:

TypeError: invalid type promotion

但是如果我首先将 datetime64 转换为 datetime

t_col2 =t_col.astype('datetime64[h]').tolist()

m = np.c_[t_col2, d_col]

有用。

问题:当数据和时间为 datetime64 时,为什么我不能合并数组?为什么我需要将其转换为日期时间?

4

1 回答 1

0
In [266]: t = np.arange('2010-09-01','2010-09-02', dtype='datetime64[6h]') 
     ...:  
     ...: d = np.linspace(0,1,len(t))                                           
In [267]: t                                                                     
Out[267]: 
array(['2010-09-01T00', '2010-09-01T06', '2010-09-01T12', '2010-09-01T18'],
      dtype='datetime64[6h]')
In [268]: d                                                                     
Out[268]: array([0.        , 0.33333333, 0.66666667, 1.        ])

使用vstack代替c_(只是为了方便):

In [269]: np.vstack((t,d))                                                      
...
<__array_function__ internals> in concatenate(*args, **kwargs)

TypeError: invalid type promotion

出现错误是因为结果需要为 1 dtype,浮点数或datetime64. numpy数组需要统一的 dtype(如 MATLAB matrix)。

tolistastype(object)datetime64数组变成datatime对象。这些可以与浮点数连接,也可以转换为对象:

In [270]: np.vstack((t.tolist(),d))                                             
Out[270]: 
array([[datetime.datetime(2010, 9, 1, 0, 0),
        datetime.datetime(2010, 9, 1, 6, 0),
        datetime.datetime(2010, 9, 1, 12, 0),
        datetime.datetime(2010, 9, 1, 18, 0)],
       [0.0, 0.3333333333333333, 0.6666666666666666, 1.0]], dtype=object)

In [271]: np.vstack((t.astype(object),d))                                       
Out[271]: 
array([[datetime.datetime(2010, 9, 1, 0, 0),
        datetime.datetime(2010, 9, 1, 6, 0),
        datetime.datetime(2010, 9, 1, 12, 0),
        datetime.datetime(2010, 9, 1, 18, 0)],
       [0.0, 0.3333333333333333, 0.6666666666666666, 1.0]], dtype=object)

这个对象 dtype 数组就像一个 MATLAB cell,包含不同的元素。

另一种选择是制作结构化数组(有点像 MATLAB struct):

In [274]: arr  = np.zeros(4, dtype=[('t',t.dtype), ('d',d.dtype)])              
In [275]: arr                                                                   
Out[275]: 
array([('1970-01-01T00', 0.), ('1970-01-01T00', 0.),
       ('1970-01-01T00', 0.), ('1970-01-01T00', 0.)],
      dtype=[('t', '<M8[6h]'), ('d', '<f8')])
In [276]: arr['t']=t; arr['d']=d                                                
In [277]: arr                                                                   
Out[277]: 
array([('2010-09-01T00', 0.        ), ('2010-09-01T06', 0.33333333),
       ('2010-09-01T12', 0.66666667), ('2010-09-01T18', 1.        )],
      dtype=[('t', '<M8[6h]'), ('d', '<f8')])

编辑


从这两个数组构造结构化数组的另一种方法:

In [286]: import numpy.lib.recfunctions as rf     
In [293]: rf.merge_arrays((t,d))                                                
Out[293]: 
array([('2010-09-01T00', 0.        ), ('2010-09-01T06', 0.33333333),
       ('2010-09-01T12', 0.66666667), ('2010-09-01T18', 1.        )],
      dtype=[('f0', '<M8[6h]'), ('f1', '<f8')])

在内部,它与我第一次演示的类似。

于 2019-10-03T18:11:43.447 回答