Pandas `.to_pydatetime()` 在 DataFrame 中不起作用

Adr*_*ter 5 python-3.x python-datetime pandas

我有这样的字符串'03-21-2019',我想转换为本地 Python 日期时间对象:即datetime.datetime类型。转换很容易通过pandas

import pandas as pd
import datetime as dt

date_str = '03-21-2019'
pd_Timestamp = pd.to_datetime(date_str)
py_datetime_object = pd_Timestamp.to_pydatetime()
print(type(py_datetime_object))
Run Code Online (Sandbox Code Playgroud)

结果

<class 'datetime.datetime'>
Run Code Online (Sandbox Code Playgroud)

这正是我想要的,因为我想timedelta通过从另一个中减去其中一个来计算's - 在本机 Pythondatetime.datetime类中完美定义。但是,我的数据在pd.DataFrame. 当我尝试以下代码时:

import pandas as pd
import datetime as dt

df = pd.DataFrame(columns=['Date'])
df.loc[0] = ['03-21-2019']
df['Date'] = df['Date'].apply(lambda x:
                              pd.to_datetime(x).to_pydatetime())
print(type(df['Date'].iloc[0]))
Run Code Online (Sandbox Code Playgroud)

结果是

<class 'pandas._libs.tslibs.timestamps.Timestamp'>
Run Code Online (Sandbox Code Playgroud)

这是错误的类型,我一生都无法弄清楚为什么只有一部分lambda表达式被评估(即字符串到熊猫时间戳),而不是最后一部分(即熊猫-时间戳到日期时间。日期时间)。如果我显式定义函数,而不是使用lambda表达式,它也不起作用:

import pandas as pd
import datetime as dt


def to_native_datetime(date_str: str) -> dt.datetime:
    return pd.to_datetime(date_str).to_pydatetime()


df = pd.DataFrame(columns=['Date'])
df.loc[0] = ['03-21-2019']
df['Date'] = df['Date'].apply(to_native_datetime)
print(type(df['Date'].iloc[0]))
Run Code Online (Sandbox Code Playgroud)

结果和之前一样。它肯定在执行函数的一部分,因为结果不再是字符串。但我想要本机 Pythondatetime.datetime对象,我看不到它。这看起来像是 中的一个错误pandas,但我当然愿意将其视为我的用户错误。

为什么我不能datetime.datetimepandas.DataFrame字符串列中获取本机对象?

我看过this threadthis one,但他们都没有回答我的问题。

[编辑]:还有更奇怪的事情:

import pandas as pd
import datetime as dt


def to_native_datetime(date_str: str) -> dt.datetime:
    return dt.datetime.strptime(date_str, '%m-%d-%Y')


df = pd.DataFrame(columns=['Date'])
df.loc[0] = ['03-21-2019']
df['Date'] = df['Date'].apply(to_native_datetime)
print(type(df['Date'].iloc[0]))
Run Code Online (Sandbox Code Playgroud)

在这里我什pandas至没有用来转换字符串,我仍然得到一个

<class 'pandas._libs.tslibs.timestamps.Timestamp'>
Run Code Online (Sandbox Code Playgroud)

出来吧!

非常感谢您的时间!

[进一步编辑]:显然,在此线程中,在 Nehal J Wani 的回答中,pandas当您分配到pd.DataFrame. 这不是我想听到的,但显然,当我读出pd.DataFrame.

Lio*_*yon 7

感谢Sarah\xc2\xa0Messer \xe2\x80\x99s 的回答和这个我可以通过将数组重新分配回数据帧并强制其 dtype 为对象来解决问题:

\n
arr_date = df[\'Date\'].dt.to_pydatetime()\ndf[\'Date\']= pd.Series(arr_date, dtype=object)\n
Run Code Online (Sandbox Code Playgroud)\n

例子:

\n
import pandas as pd\nfrom datetime import datetime\n\ndf = pd.DataFrame({"date": [datetime(2021, 8, 28, 4, 10), datetime(2021, 8, 28, 4, 10)]})\ndf.dtypes\n\n#   date    datetime64[ns]\n#   dtype: object\n\narr_date = df["date"].dt.to_pydatetime()\ndf["date"] = pd.Series(arr_date, dtype="object")\ndf.dtypes\n\n#   date    object\n#   dtype: object\n\ndf.iloc[0,0]\n\n# datetime.datetime(2021, 8, 28, 4, 10)\n
Run Code Online (Sandbox Code Playgroud)\n


Sar*_*ser 2

根据您的实际目标,您有几个没有直接提及的选项。

1) 如果你有一个静态日期时间对象或一列 (pandas) 时间戳,并且你愿意处理 Pandas 版本的 Timedelta ( pandas._libs.tslibs.timedeltas.Timedelta),你可以直接在 pandas 中进行减法:

df = pd.DataFrame(columns=['Date'])
df.loc[0] = [pd.to_datetime('03-21-2019')]
df.loc[:, 'Offset'] = pd.Series([datetime.now()])
df.loc[:, 'Diff1'] = df['Offset'] - df['Date']
df.loc[:, 'Diff2'] = df['Date'] - datetime.now()
Run Code Online (Sandbox Code Playgroud)

2)如果您不关心Dataframes,但愿意处理列表/numpy数组,您可以通过对系列而不是单个元素进行操作将日期时间转换为python原生日期时间。下面arr是一些numpy.ndarray对象datetime.datetime。您可以使用以下命令将其更改为常规日期时间列表list(arr)

arr = df['Date'].dt.to_pydatetime()
Run Code Online (Sandbox Code Playgroud)