将Pandas数据框中的多个列更改为日期时间格式。

55

我有一个由13列和55,000行组成的数据框,我正在尝试将其中的5行转换为日期时间格式,目前它们返回的类型是“object”,我需要将这些数据转换为机器学习所需的格式。我知道如果我执行以下操作:

data['birth_date'] = pd.to_datetime(data[birth_date], errors ='coerce')
它将返回一个日期时间列,但我还想对其他四个列执行此操作,有没有一行代码可以调用它们所有?我认为我不能像索引那样去做。
data[:,7:12]
谢谢!

1
我不确定是否有一种函数可以同时转换多列,但我知道read_csv有一个parse_dates参数,可以在首次导入数据时将您想要转换的所有列的列表传递给它。 - Ted Petrou
8个回答

79
你可以使用 applypd.to_datetime 来遍历每一列。
data.iloc[:, 7:12] = data.iloc[:, 7:12].apply(pd.to_datetime, errors='coerce')

作为 pandas 1.3.0 中的一部分变更iloc/loc在赋值时不再更新列的数据类型。改为直接使用列标签:
cols = data.columns[7:12]
data[cols] = data[cols].apply(pd.to_datetime, errors='coerce')

简短问题,在这种情况下使用map()方法会更好,不是吗? - David
1
“map”和“apply”都可以接受函数,这就是为什么像您这样的用户会感到困惑。我只使用“map”来使用字典/系列进行“文字映射”。我只使用“apply”来执行函数。“apply”还具有一些额外的功能。 - Ted Petrou
2
使用 errors='coerce',无效的日期将被分配给 NaT - 这里 的第二个示例展示了这一点。如果使用 ignore 而不是 coerce,它将忽略它是无效规范的事实,并返回一个(可能)无效/不正确的日期。 - edesz
我有同样的问题,但我只需要将列名从字符串(例如:2020-Q4)更改为日期时间,而不影响行。这该怎么做? - beshr

44
my_df[['column1','column2']] =     
my_df[['column1','column2']].apply(pd.to_datetime, format='%Y-%m-%d %H:%M:%S.%f')

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


当我这样做时,如何保留数据框的其他列? - jvqp
@JessicaVoigt 在 = 左边只有选定的列会被覆盖;my_df 中剩余的列将保持不变。你可以使用 my_df[['column1','column2']].apply(...) 来分别赋值给新列 new_1new_2 - Nick P

19

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

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


2
如果数据框很深且日期不是正态分布的,则数字看起来并不那么令人印象深刻。我在我的数据框(273771,)上运行了代码,to_datetime时间为1分13秒,而查找时间为59秒。 - smishra
@smishra 很可能这取决于您的输入数据。如果有很多重复项,SerialDev的方法是快速查找而不是转换。 - gies0r
这看起来很不错。我们如何将这个序列对象作为s传递?df['Date'] = lookup(['Date'])? - BrianBeing

12

如果您希望在加载时进行转换,您可以做如下操作:

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

2

首先,您需要从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'))

1

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

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

0

read_csv()

除了@smishra的答案之外,当导入.csv文件时,您可以使用infer-datetime-format来推断日期格式,如此处所讨论的。这只能在系列具有一致的日期格式时使用,但会加快日期的导入速度。

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)

-1
data.iloc[:, 7:12]=data.iloc[:, 7:12].astype('datetime64[ns]')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接