【问题标题】:How do I convert strings in a Pandas data frame to a 'date' data type?如何将 Pandas 数据框中的字符串转换为“日期”数据类型?
【发布时间】:2013-05-27 00:24:14
【问题描述】:

我有一个 Pandas 数据框,其中一列包含格式为 YYYY-MM-DD 的日期字符串

例如'2013-10-28'

目前该列的dtypeobject

如何将列值转换为 Pandas 日期格式?

【问题讨论】:

    标签: python date pandas


    【解决方案1】:

    基本上等同于@waitingkuo,但我会在这里使用pd.to_datetime(它看起来更简洁,并提供了一些额外的功能,例如dayfirst):

    In [11]: df
    Out[11]:
       a        time
    0  1  2013-01-01
    1  2  2013-01-02
    2  3  2013-01-03
    
    In [12]: pd.to_datetime(df['time'])
    Out[12]:
    0   2013-01-01 00:00:00
    1   2013-01-02 00:00:00
    2   2013-01-03 00:00:00
    Name: time, dtype: datetime64[ns]
    
    In [13]: df['time'] = pd.to_datetime(df['time'])
    
    In [14]: df
    Out[14]:
       a                time
    0  1 2013-01-01 00:00:00
    1  2 2013-01-02 00:00:00
    2  3 2013-01-03 00:00:00
    

    处理ValueErrors
    如果你遇到做事的情况

    df['time'] = pd.to_datetime(df['time'])
    

    抛出一个

    ValueError: Unknown string format
    

    这意味着您的值无效(不可强制)。如果您可以将它们转换为pd.NaT,您可以将errors='coerce' 参数添加到to_datetime

    df['time'] = pd.to_datetime(df['time'], errors='coerce')
    

    【讨论】:

    • 嗨伙计们,@AndyHayden 你能从日期中删除时间部分吗?我不需要那部分?
    • 在 pandas 的 0.13.1 中不显示尾随的 00:00:00。
    • 那么在其他版本中,我们如何删除/不显示它们?
    • 我认为这不能很好地完成,有讨论添加 date_format 像 float_format (你已经看到了)。我还是建议升级。
    • 我的问题是我的日期是这种格式... 41516.43,我收到了这个错误。我希望它在新专栏中返回类似 2014-02-03 的内容?!错误:#convert date values in the "load_date" column to dates budget_dataset['date_last_load'] = pd.to_datetime(budget_dataset['load_date']) budget_dataset -c:2: SettingWithCopyWarning: A value is trying to set on a从 DataFrame 复制切片。尝试改用 .loc[row_index,col_indexer] = value
    【解决方案2】:

    使用astype

    In [31]: df
    Out[31]: 
       a        time
    0  1  2013-01-01
    1  2  2013-01-02
    2  3  2013-01-03
    
    In [32]: df['time'] = df['time'].astype('datetime64[ns]')
    
    In [33]: df
    Out[33]: 
       a                time
    0  1 2013-01-01 00:00:00
    1  2 2013-01-02 00:00:00
    2  3 2013-01-03 00:00:00
    

    【讨论】:

    • 很好 - 谢谢 - 我如何摆脱每个日期结束时的 00:00:00?
    • 熊猫时间戳有日期和时间。你的意思是把它转换成python日期对象吗?
    • 您可以通过df['time'] = [time.date() for time in df['time']]进行转换
    • [ns] 是什么意思,能否将文本字符串设为日期并删除该日期的时间部分?
    • @yoshiserry 它是纳秒,一旦正确转换(以纳秒为单位的纪元时间),日期就会存储在引擎盖下。
    【解决方案3】:

    我想很多数据从 CSV 文件进入 Pandas,在这种情况下,您可以在初始 CSV 读取期间简单地转换日期:

    dfcsv = pd.read_csv('xyz.csv', parse_dates=[0]) 其中 0 指的是日期所在的列。
    如果您希望日期成为索引,也可以在其中添加 , index_col=0

    https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html

    【讨论】:

    【解决方案4】:

    现在你可以df['column'].dt.date

    请注意,对于 datetime 对象,如果您没有看到它们都是 00:00:00 的时间,那不是 pandas。那是 iPython notebook 试图让事情看起来很漂亮。

    【讨论】:

    • 这个对我不起作用,它抱怨:只能使用带有 datetimelike 值的 .dt 访问器
    • 您可能必须先执行df[col] = pd.to_datetime(df[col]) 才能将您的列转换为日期时间对象。
    • 这个答案的问题是它将列转换为dtype = object,这比熊猫中真正的datetime dtype占用更多的内存。
    • .dt.date 绝对不应该与任何大型数据集一起使用,因为:(1)它使用 dtype object 如果数据集很大(有 2 亿或更多行)(2)fastparquet写入parquet失败。
    • 此人没有提及数据集的大小或镶木地板。
    【解决方案5】:

    如果您想获取 DATE 而不是 DATETIME 格式:

    df["id_date"] = pd.to_datetime(df["id_date"]).dt.date
    

    【讨论】:

    • .dt.date 绝对不应与任何大型数据集一起使用,因为:(1)它使用 dtype object 如果数据集很大(有 2 亿或更多行)(2)fastparquet写入parquet失败。
    【解决方案6】:

    执行此操作的另一种方法,如果您有多个列要转换为日期时间,则此方法效果很好。

    cols = ['date1','date2']
    df[cols] = df[cols].apply(pd.to_datetime)
    

    【讨论】:

    • 问题询问日期而不是日期时间。
    • @MarkAndersen 只要您的列中只有date 值,转换为日期时间将仅保留相关信息。如果您使用 df['datetime_col'].dt.date 显式转换,这将导致 object dtype;内存管理丢失。
    • 这里没有理由使用.apply,考虑到直接使用pd.to_datetime 就可以了。
    【解决方案7】:

    可能需要将日期转换为不同的频率。在这种情况下,我建议按日期设置索引。

    #set an index by dates
    df.set_index(['time'], drop=True, inplace=True)
    

    在此之后,您可以更轻松地转换为您最需要的日期格式类型。下面,我依次转换为多种日期格式,最终得到一组月初的每日日期。

    #Convert to daily dates
    df.index = pd.DatetimeIndex(data=df.index)
    
    #Convert to monthly dates
    df.index = df.index.to_period(freq='M')
    
    #Convert to strings
    df.index = df.index.strftime('%Y-%m')
    
    #Convert to daily dates
    df.index = pd.DatetimeIndex(data=df.index)
    

    为简洁起见,我没有在上面的每一行之后运行以下代码:

    print(df.index)
    print(df.index.dtype)
    print(type(df.index))
    

    这给了我以下输出:

    Index(['2013-01-01', '2013-01-02', '2013-01-03'], dtype='object', name='time')
    object
    <class 'pandas.core.indexes.base.Index'>
    
    DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03'], dtype='datetime64[ns]', name='time', freq=None)
    datetime64[ns]
    <class 'pandas.core.indexes.datetimes.DatetimeIndex'>
    
    PeriodIndex(['2013-01', '2013-01', '2013-01'], dtype='period[M]', name='time', freq='M')
    period[M]
    <class 'pandas.core.indexes.period.PeriodIndex'>
    
    Index(['2013-01', '2013-01', '2013-01'], dtype='object')
    object
    <class 'pandas.core.indexes.base.Index'>
    
    DatetimeIndex(['2013-01-01', '2013-01-01', '2013-01-01'], dtype='datetime64[ns]', freq=None)
    datetime64[ns]
    <class 'pandas.core.indexes.datetimes.DatetimeIndex'>
    

    【讨论】:

      【解决方案8】:

      为了完整起见,另一种选择,可能不是最直接的,有点类似于@SSS 提出的,但使用日期时间库是:

      import datetime
      df["Date"] = df["Date"].apply(lambda x: datetime.datetime.strptime(x, '%Y-%d-%m').date())
      

      【讨论】:

        【解决方案9】:
         #   Column          Non-Null Count   Dtype         
        ---  ------          --------------   -----         
         0   startDay        110526 non-null  object
         1   endDay          110526 non-null  object
        
        import pandas as pd
        
        df['startDay'] = pd.to_datetime(df.startDay)
        
        df['endDay'] = pd.to_datetime(df.endDay)
        
         #   Column          Non-Null Count   Dtype         
        ---  ------          --------------   -----         
         0   startDay        110526 non-null  datetime64[ns]
         1   endDay          110526 non-null  datetime64[ns]
        

        【讨论】:

        • 不,这会将其转换为 'datetime64[ns]' 类型而不是 'date' 类型。这些是不同的东西。
        【解决方案10】:

        尝试使用 pd.to_datetime 函数将其中一行转换为时间戳,然后使用 .map 将公式映射到整个列

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-18
          • 1970-01-01
          • 2013-03-06
          • 1970-01-01
          • 2021-04-10
          • 2023-03-09
          相关资源
          最近更新 更多