【问题标题】:change multiple columns in pandas dataframe to datetime将熊猫数据框中的多列更改为日期时间
【发布时间】:2017-05-21 17:11:30
【问题描述】:

我有一个包含 13 列和 55,000 行的数据框,我正在尝试将其中的 5 行转换为日期时间,现在它们返回类型“对象”,我需要转换这些数据以进行机器学习我知道如果我做

data['birth_date'] = pd.to_datetime(data[birth_date], errors ='coerce')

它将返回一个日期时间列,但我也想为其他 4 个列执行此操作,我可以写一行来调用所有列吗?我不认为我可以像

data[:,7:12]

谢谢!

【问题讨论】:

  • 我不确定是否有一个函数可以同时转换多个列,但我知道read_csv 有一个parse_dates 参数,它可以列出你想要的所有列喜欢在第一次导入数据时进行转换。

标签: python datetime pandas


【解决方案1】:

您可以使用apply 使用pd.to_datetime 遍历每一列

data.iloc[:, 7:12] = data.iloc[:, 7:12].apply(pd.to_datetime, errors='coerce')

作为the changes in pandas 1.3.0 的一部分,iloc/loc 将不再更新分配时的列 dtype。直接使用列标签:

cols = data.columns[7:12]
data[cols] = data[cols].apply(pd.to_datetime, errors='coerce')

【讨论】:

  • 快速提问,在这种情况下使用 map() 方法不是更好吗?
  • mapapply 都可以接受函数,这就是为什么这会让像你这样的用户感到困惑。我只使用map 用字典/系列进行“文字映射”。我只将apply 用于函数。 apply 也有一些额外的功能。
  • 对于errors='coerce',无效日期被分配给NaT - here 的第二个示例显示了这一点。如果使用ignore 而不是coerce,它将忽略它是无效规范这一事实,并仅返回(可能)无效/不正确的日期。
  • 我有同样的问题,但我只需要将列名从字符串(例如:2020-Q4)更改为日期时间而不影响行。如何做到这一点?
【解决方案2】:

read_csv()

添加到@smishra 答案。导入 .csv 时,您可以使用 infer-datetime-format 推断日期,如 here 所述。这只能在系列具有一致的日期格式但会加快日期的导入时使用。

read_excel()

还有read_excel() 函数可用于导入和处理日期。您可以向parse_dates 参数传递列名称或编号的列表。

parse_dates = [7,8,9,10,11]
data = pd.read_excel('file_to_read.csv', sheet_name='Sheet1', parse_dates=parse_dates)

【讨论】:

    【解决方案3】:

    与接受的答案略有不同, loc 也可以:

    dx.loc[:,['birth_date','death_date']] = dx.loc[:,['birth_date','death_date']].apply(pd.to_datetime, errors='coerce')
    

    【讨论】:

      【解决方案4】:
      data.iloc[:, 7:12]=data.iloc[:, 7:12].astype('datetime64[ns]')
      

      【讨论】:

        【解决方案5】:

        如果你想在加载时进行转换,你可以这样做

        date_columns = ['c1','c2', 'c3', 'c4', 'c5']
        data = pd.read_csv('file_to_read.csv', parse_dates=date_columns)
        

        【讨论】:

          【解决方案6】:
          my_df[['column1','column2']] =     
          my_df[['column1','column2']].apply(pd.to_datetime, format='%Y-%m-%d %H:%M:%S.%f')
          

          注意:当然可以根据需要更改格式。

          【讨论】:

          • 这样做时如何保留数据框的其他列?
          • @JessicaVoigt = 左侧仅覆盖选定的列; my_df 中的其余列将保持不变。您可以使用my_df[['new_1','new_2']] = my_df[['column1','column2']].apply(...) 分别分配给新列。
          【解决方案7】:

          首先您需要从data 中提取您感兴趣的所有列,然后您可以使用pandas applymapto_datetime 应用于提取帧中的每个元素,我假设您知道您想要的列的索引提取,在下面的代码中提取第三到第十六列的列名。您也可以定义一个列表并将列的名称添加到其中并使用它,您可能还需要传递 DateTime 条目的日期/时间格式

          import pandas as pd
          
          cols_2_extract = data.columns[2:15]
          
          data[cols_2_extract] = data[cols_2_extract].applymap(lambda x : pd.to_datetime(x, format = '%d %M %Y'))
          

          【讨论】:

            【解决方案8】:

            如果性能是一个问题,我建议使用以下函数将这些列转换为 date_time:

            def lookup(s):
                """
                This is an extremely fast approach to datetime parsing.
                For large data, the same dates are often repeated. Rather than
                re-parse these, we store all unique dates, parse them, and
                use a lookup to convert all dates.
                """
                dates = {date:pd.to_datetime(date) for date in s.unique()}
                return s.apply(lambda v: dates[v])
            
            to_datetime: 5799 ms
            dateutil:    5162 ms
            strptime:    1651 ms
            manual:       242 ms
            lookup:        32 ms
            

            来源: https://github.com/sanand0/benchmarks/tree/master/date-parse

            【讨论】:

            • 如果数据框很深并且日期不是正态分布的,那么这些数字看起来就不那么令人印象深刻了。我在我的数据框 (273771,) 上运行代码,to_datetime 时间是 1min13 秒,而查找时间是 59 秒。
            • @smishra 这很可能取决于您的输入数据。如果有很多重复。 SerialDev 的方法比快速查找而不是转换。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-04-25
            • 2017-07-24
            • 2019-01-24
            • 1970-01-01
            • 2021-07-29
            • 1970-01-01
            • 2019-07-20
            相关资源
            最近更新 更多