将Pandas Column转换为DateTime

Chr*_*ris 184 python datetime pandas

我在pandas DataFrame中有一个字段,它以字符串格式导入.它应该是一个日期时间变量.如何将其转换为日期时间列,然后根据日期进行过滤.

例:

  • DataFrame名称:raw_data
  • 专栏名称:Mycol
  • 列中的值格式:'05SEP2014:00:00:00.000'

chr*_*isb 337

使用该to_datetime功能,指定匹配数据的格式.

raw_data['Mycol'] =  pd.to_datetime(raw_data['Mycol'], format='%d%b%Y:%H:%M:%S.%f')
Run Code Online (Sandbox Code Playgroud)

  • 注意:不需要`format`参数.`to_datetime`很聪明.继续尝试,而不是尝试匹配您的数据. (54认同)
  • 省略格式字符串可能会导致此操作因许多记录而变慢.[这个答案](/sf/answers/2242444011/)讨论了原因.如果你不包含格式字符串,看起来`infer_datetime_format = True`也可以将解析速度提高到~5-10x(根据pandas docs). (10认同)
  • “format”不是必需的,但传递它会使转换运行得更快。有关更多信息,请参阅[此答案](/sf/answers/5269420411/)。 (6认同)
  • 不是非常聪明.即使某些列明确地以dayfirst = True格式显示,对于同一列中的其他列,它仍将默认为dayfirst = False.因此,使用显式格式规范或至少使用dayfirst参数更安全. (4认同)
  • 为了避免`SettingWithCopyWarning`,请使用@ darth-behfans /sf/answers/2994116751/ (2认同)
  • 如果你只是想要时间而不是约会怎么办? (2认同)

ber*_*nie 43

您可以使用DataFrame方法.apply()操作Mycol中的值:

>>> df = pd.DataFrame(['05SEP2014:00:00:00.000'],columns=['Mycol'])
>>> df
                    Mycol
0  05SEP2014:00:00:00.000
>>> import datetime as dt
>>> df['Mycol'] = df['Mycol'].apply(lambda x: 
                                    dt.datetime.strptime(x,'%d%b%Y:%H:%M:%S.%f'))
>>> df
       Mycol
0 2014-09-05
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!这很好,因为它更广泛适用,但另一个答案更直接。我很难决定我更喜欢哪个:) (2认同)
  • 我更喜欢这个答案,因为它产生一个datetime对象而不是pandas.tslib.Timestamp对象 (2认同)

小智 27

使用 pandasto_datetime函数将列解析为 DateTime。此外,通过使用infer_datetime_format=True,它会自动检测格式并将提到的列转换为日期时间。

import pandas as pd
raw_data['Mycol'] =  pd.to_datetime(raw_data['Mycol'], infer_datetime_format=True)
Run Code Online (Sandbox Code Playgroud)


Gil*_*gio 17

省时间:

raw_data['Mycol'] = pd.to_datetime(raw_data['Mycol'])
Run Code Online (Sandbox Code Playgroud)


Vla*_*den 15

如果要转换的列不止一个,则可以执行以下操作:

df[["col1", "col2", "col3"]] = df[["col1", "col2", "col3"]].apply(pd.to_datetime)
Run Code Online (Sandbox Code Playgroud)

  • 如果这些列中有不同的日期时间格式,您可以尝试使用“format”参数,例如:“apply(pd.to_datetime, format='mixed')” (2认同)

小智 12

raw_data['Mycol'] =  pd.to_datetime(raw_data['Mycol'], format='%d%b%Y:%H:%M:%S.%f')
Run Code Online (Sandbox Code Playgroud)

但是它会导致Python警告的A值试图在DataFrame的切片副本上设置.尝试使用.loc[row_indexer,col_indexer] = value替代

我猜这是由于一些链式索引.

  • 我尝试了几次,但这有效: **raw_data.loc[:,'Mycol'] = pd.to_datetime(raw_data['Mycol'], format='%d%b%Y:%H:%M: %S.%f')** (9认同)

cot*_*ail 10

设置正确format=比让 pandas 找出要快得多1

长话短说,像chrisb 的帖子format=那样从头开始传递正确的信息比让 pandas 找出格式要快得多,特别是当格式包含时间部分时。大于 10k 行的数据帧的运行时差异是巨大的(大约快 25 倍,所以我们说的是几分钟而不是几秒)。所有有效的格式选项都可以在https://strftime.org/找到。

性能图

errors='coerce'很有用

如果某些行的格式不正确或根本不是日期时间,errors=则参数非常有用,以便您可以转换有效行并稍后处理包含无效值的行。

df['date'] = pd.to_datetime(
    df['date'], format='%d%b%Y:%H:%M:%S.%f', errors='coerce')

# for multiple columns
df[['start', 'end']] = df[['start', 'end']].apply(
    pd.to_datetime, format='%d%b%Y:%H:%M:%S.%f', errors='coerce')
Run Code Online (Sandbox Code Playgroud)
沉默SettingWithCopyWarning

顺便说一句,如果您收到此警告,则意味着您的数据框可能是通过过滤另一个数据框创建的。启用写时复制就可以了。(有关更多信息,请参阅这篇文章)。

pd.set_option('copy_on_write', True)
df['date'] = pd.to_datetime(df['date'], format='%d%b%Y:%H:%M:%S.%f')
Run Code Online (Sandbox Code Playgroud)

1用于生成 timeit 测试图的代码。

import perfplot
from random import choices
from datetime import datetime

mdYHMSf = range(1,13), range(1,29), range(2000,2024), range(24), *[range(60)]*2, range(1000)
perfplot.show(
    kernels=[lambda x: pd.to_datetime(x), 
             lambda x: pd.to_datetime(x, format='%m/%d/%Y %H:%M:%S.%f'), 
             lambda x: pd.to_datetime(x, infer_datetime_format=True),
             lambda s: s.apply(lambda x: datetime.strptime(x, '%m/%d/%Y %H:%M:%S.%f'))],
    labels=["pd.to_datetime(df['date'])", 
            "pd.to_datetime(df['date'], format='%m/%d/%Y %H:%M:%S.%f')", 
            "pd.to_datetime(df['date'], infer_datetime_format=True)", 
            "df['date'].apply(lambda x: datetime.strptime(x, '%m/%d/%Y %H:%M:%S.%f'))"],
    n_range=[2**k for k in range(20)],
    setup=lambda n: pd.Series([f"{m}/{d}/{Y} {H}:{M}:{S}.{f}" 
                               for m,d,Y,H,M,S,f in zip(*[choices(e, k=n) for e in mdYHMSf])]),
    equality_check=pd.Series.equals,
    xlabel='len(df)'
)
Run Code Online (Sandbox Code Playgroud)

如果该列包含多种格式,请参阅将混合格式字符串列转换为日期时间 Dtype