Как можно избежать автоматического преобразования np.datetime64 в datetime при добавлении его в массив numpy? - PullRequest
0 голосов
/ 20 января 2019

В следующем примере элементы с dtype np.datetime64 автоматически преобразуются в datetime.datetime, когда они добавляются в другой массив numpy.

Как мне избежать этого автоконверсии?

import numpy as np
a = np.array([['2018-04-01T15:30:00'],
       ['2018-04-01T15:31:00'],
       ['2018-04-01T15:32:00'],
       ['2018-04-01T15:33:00'],
       ['2018-04-01T15:34:00']], dtype='datetime64[s]')
c = np.array([0,1,2,3,4]).reshape(-1,1)
c = c.astype("object")
d = np.append(c,a,axis=1)
d

.

array([[0, datetime.datetime(2018, 4, 1, 15, 30)],
       [1, datetime.datetime(2018, 4, 1, 15, 31)],
       [2, datetime.datetime(2018, 4, 1, 15, 32)],
       [3, datetime.datetime(2018, 4, 1, 15, 33)],
       [4, datetime.datetime(2018, 4, 1, 15, 34)]], dtype=object)

Ответы [ 2 ]

0 голосов
/ 20 января 2019

Использовать массив записей вместо dtype=object

Исправьте это путем создания массива, который может правильно обрабатывать столбцы разных типов. Самый простой способ сделать это - создать массив записей , например:

rarr = np.rec.fromarrays([a, c], names=('date', 'val'))

print(rarr)
# output
#     rec.array([[('2018-04-01T15:30:00', 0)],
#                [('2018-04-01T15:31:00', 1)],
#                [('2018-04-01T15:32:00', 2)],
#                [('2018-04-01T15:33:00', 3)],
#                [('2018-04-01T15:34:00', 4)]],
#               dtype=[('date', '<M8[s]'), ('val', '<i8')])

print(rarr.date)
# output
#     array([['2018-04-01T15:30:00'],
#            ['2018-04-01T15:31:00'],
#            ['2018-04-01T15:32:00'],
#            ['2018-04-01T15:33:00'],
#            ['2018-04-01T15:34:00']], dtype='datetime64[s]')

Как указывает hpaulj, независимо от того, что вы делаете, вы не можете добавить (или иным образом легко манипулировать) столбец datetime64 в массиве dtype=object. Однако это легко сделать с массивом записей:

print(rarr.date + np.array(10, 'timedelta64[m]'))
# output
#     array([['2018-04-01T15:40:00'],
#            ['2018-04-01T15:41:00'],
#            ['2018-04-01T15:42:00'],
#            ['2018-04-01T15:43:00'],
#            ['2018-04-01T15:44:00']], dtype='datetime64[s]')
0 голосов
/ 20 января 2019

Иногда нам нужно создать «пустой» массив объектов и заполнить его по частям.

In [57]: d = np.empty((5,2), object)
In [58]: d
Out[58]: 
array([[None, None],
       [None, None],
       [None, None],
       [None, None],
       [None, None]], dtype=object)

Мы можем заполнить его столбцами, но результат такой же, как у concatenate (donне используйте np.append):

In [59]: d[:,0] = c.ravel()
In [60]: d[:,1] = a.ravel()
In [61]: d
Out[61]: 
array([[0, datetime.datetime(2018, 4, 1, 15, 30)],
       [1, datetime.datetime(2018, 4, 1, 15, 31)],
       [2, datetime.datetime(2018, 4, 1, 15, 32)],
       [3, datetime.datetime(2018, 4, 1, 15, 33)],
       [4, datetime.datetime(2018, 4, 1, 15, 34)]], dtype=object)

Как и в случае a.astype(object), он «распаковал» даты.

Но если я назначу элементы один за другим:

In [62]: for i in range(5):
    ...:     d[i,1]=a[i,0]
    ...:     
In [63]: d
Out[63]: 
array([[0, numpy.datetime64('2018-04-01T15:30:00')],
       [1, numpy.datetime64('2018-04-01T15:31:00')],
       [2, numpy.datetime64('2018-04-01T15:32:00')],
       [3, numpy.datetime64('2018-04-01T15:33:00')],
       [4, numpy.datetime64('2018-04-01T15:34:00')]], dtype=object)

Но каково значение такого массива?

Я могу добавить временную дельту к исходному массиву времени:

In [67]: a + np.array(10, 'timedelta64[m]')
Out[67]: 
array([['2018-04-01T15:40:00'],
       ['2018-04-01T15:41:00'],
       ['2018-04-01T15:42:00'],
       ['2018-04-01T15:43:00'],
       ['2018-04-01T15:44:00']], dtype='datetime64[s]')

, но я не могу сделать то же самое сстолбец массива объектов:

In [68]: d[:,1] + np.array(10, 'timedelta64[m]')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-68-f82827d3d355> in <module>()
----> 1 d[:,1] + np.array(10, 'timedelta64[m]')

TypeError: ufunc add cannot use operands with types dtype('O') and dtype('<m8[m]')

Я должен явно перебрать объекты:

In [70]: for i in range(5):
    ...:     d[i,1] += np.array(i*10, 'timedelta64[m]')
    ...:     
In [71]: d
Out[71]: 
array([[0, numpy.datetime64('2018-04-01T15:30:00')],
       [1, numpy.datetime64('2018-04-01T15:41:00')],
       [2, numpy.datetime64('2018-04-01T15:52:00')],
       [3, numpy.datetime64('2018-04-01T16:03:00')],
       [4, numpy.datetime64('2018-04-01T16:14:00')]], dtype=object)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...