将列数据类型从时间戳更改为datetime64

时间:2019-07-02 18:24:46

标签: python-3.x pandas dataframe numpy-ndarray python-datetime

我有一个要从Excel读取的数据库作为熊猫数据框,日期在时间戳记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 个答案:

答案 0 :(得分:1)

Pandas在将日期时间分配给DataFrame时会尝试通过storing them as NumPy datetime64[ns] values标准化所有日期时间。但是,当您尝试访问各个datetime64值时,they are returned as Timestamps

There is a way来防止这种自动转换的发生:将一系列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 dtypes数组进行的等效操作要慢得多。

您可能正在看XY problem-找到一种方法(1)可能会更有成果 与Pandas Timestamps合作,而不是试图强迫Pandas返回NumPy datetime64s或(2)处理类似datetime64的数组(例如,一系列NumPy数组),而不是单独处理值(这会导致时间戳的强制)。