Así que tengo una ndarray similar a este ejemplo:

dates = ['3/1/2020','4/15/2020','7/21/2020']
darray = np.asarray([dateutil.parser.parse(d) for d in dates], dtype='datetime64[ns]')

>>> array(['2020-03-01T00:00:00.000000000', '2020-04-15T00:00:00.000000000',
   '2020-07-21T00:00:00.000000000'], dtype='datetime64[ns]') 

darray.tolist()

>>> [1583020800000000000, 1586908800000000000, 1595289600000000000]

Así que supongo que se está convirtiendo a una cantidad de nanosegundos desde el origen POSIX (1970-01-01). ¿Hay alguna manera de evitar esta pérdida de tipo de datos?

1
ocean800 19 feb. 2020 a las 04:02

2 respuestas

La mejor respuesta

Normalmente tolist es mejor que list. Funciona completamente y es más rápido. list simplemente itera en la primera dimensión. Pero la conversión a tipos nativos de Python depende de dtype. En este caso, las unidades de tiempo hacen la diferencia.

In [559]: arr = np.array(['2020-03-01T00:00:00.000000000', '2020-04-15T00:00:00.000000000', 
     ...:    '2020-07-21T00:00:00.000000000'], dtype='datetime64[ns]')                         
In [560]: arr.shape                                                                            
Out[560]: (3,)
In [561]: arr.dtype                                                                            
Out[561]: dtype('<M8[ns]')

list es el equivalente de [x for x in arr], iteración en la primera dimensión:

In [562]: list(arr)                                                                            
Out[562]: 
[numpy.datetime64('2020-03-01T00:00:00.000000000'),
 numpy.datetime64('2020-04-15T00:00:00.000000000'),
 numpy.datetime64('2020-07-21T00:00:00.000000000')]

tolist lo convierte en objetos de Python, hasta el final:

In [563]: arr.tolist()                                                                         
Out[563]: [1583020800000000000, 1586908800000000000, 1595289600000000000]

Mientras que ns da un número entero, otras unidades de tiempo dan resultados diferentes:

In [564]: arr.astype('datetime64[D]')                                                          
Out[564]: array(['2020-03-01', '2020-04-15', '2020-07-21'], dtype='datetime64[D]')
In [565]: arr.astype('datetime64[D]').tolist()                                                 
Out[565]: 
[datetime.date(2020, 3, 1),
 datetime.date(2020, 4, 15),
 datetime.date(2020, 7, 21)]

In [566]: arr.astype('datetime64[s]').tolist()                                                 
Out[566]: 
[datetime.datetime(2020, 3, 1, 0, 0),
 datetime.datetime(2020, 4, 15, 0, 0),
 datetime.datetime(2020, 7, 21, 0, 0)]
1
hpaulj 19 feb. 2020 a las 02:37

¿Es esto lo que buscas?

>>> list(darray)
[numpy.datetime64('2020-03-01T00:00:00.000000000'),
 numpy.datetime64('2020-04-15T00:00:00.000000000'),
 numpy.datetime64('2020-07-21T00:00:00.000000000')]

La diferencia es que np.ndarray.tolist() convierte los valores a tipos de Python, mientras que list(...) deja los objetos como están. Internamente, por supuesto, ambos contienen enteros de 64 bits en ambos sentidos. Si desea convertir a objetos de fecha y hora de Python, eche un vistazo a esta pregunta. Lamentablemente, no es tan conveniente como podría ser.

2
Seb 19 feb. 2020 a las 01:14