Изменение типа данных столбца с метки времени на datetime64 - PullRequest
0 голосов
/ 02 июля 2019

У меня есть база данных, которую я читаю из Excel в качестве кадра данных pandas, и даты указываются в метке времени dtype, но мне нужно, чтобы они были в np.datetime64, чтобы я мог выполнять вычисления.

Я знаю, что функция pd.to_datetime() и метод astype(np.datetime64[ns]) работают. Однако по какой-то причине я не могу обновить свой фрейм данных для получения этого типа данных, используя код, упомянутый выше.

Я также пытался создать вспомогательный фрейм данных из исходного, с указанием только дат, которые я хочу обновить, набрав тип, преобразовав его в np.datetime64 и подключив его обратно к исходному фрейму данных:

dfi = df['dates']
dfi = pd.to_datetime(dfi)
df['dates'] = dfi

Но все равно это не работает. Я также попытался обновить значения одно за другим:

arr_i = df.index
for i in range(len(arr_i)):
    df.at[arri[l],'dates'].to_datetime64()

Редактировать Кажется, корень проблемы в том, что dtype столбца обновляется до np.datetime64, но каким-то образом, при получении отдельных значений изнутри, они по-прежнему имеют dtype = Timestamp

Есть ли у кого-нибудь предложение относительно быстрого решения?

1 Ответ

1 голос
/ 02 июля 2019

Pandas пытается стандартизировать все формы даты и времени путем , сохраняя их как значения NumPy datetime64 [ns] , когда вы присваиваете их DataFrame.Но когда вы пытаетесь получить доступ к отдельным значениям datetime64, они возвращаются как метки времени .

Однако существует способ , чтобы предотвратить автоматическое преобразование: оберните списокзначений в серии dtype object:

import numpy as np
import pandas as pd

# create some dates, merely for example
dates = pd.date_range('2000-1-1', periods=10)
# convert the dates to a *list* of datetime64s
arr = list(dates.to_numpy())
# wrap the values you wish to protect in a Series of dtype object.
ser = pd.Series(arr, dtype='object')

# assignment with `df['datetime64s'] = ser` would also work
df = pd.DataFrame({'timestamps': dates,
                   'datetime64s': ser})

df.info()
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 10 entries, 0 to 9
# Data columns (total 2 columns):
# timestamps     10 non-null datetime64[ns]
# datetime64s    10 non-null object
# dtypes: datetime64[ns](1), object(1)
# memory usage: 240.0+ bytes

print(type(df['timestamps'][0]))
# <class 'pandas._libs.tslibs.timestamps.Timestamp'>

print(type(df['datetime64s'][0]))
# <class 'numpy.datetime64'>

Но будьте осторожны!Хотя с небольшой работой вы можете обойти механизм автоматического преобразования Pandas, это может быть нецелесообразно.Во-первых, преобразование массива NumPy в список обычно является признаком того, что вы делаете что-то не так, поскольку это ухудшает производительность.Использование object массивов является плохим признаком, поскольку операции с массивами объектов, как правило, намного медленнее, чем эквивалентные операции над массивами собственных типов NumPy.

Возможно, вы смотрите на проблему XY -- может быть более полезным найти способ (1) работать с метками времени Pandas вместо попытки заставить Pandas возвращать NumPy datetime64s или (2) работать с подобными массивам datetime64 (например, сериями массивов NumPy) вместо индивидуальной обработки значений(что вызывает приведение к меткам времени).

...