将熊猫数据框中的多列更改为日期时间
Posted
技术标签:
【中文标题】将熊猫数据框中的多列更改为日期时间【英文标题】: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
参数,它可以列出你想要的所有列喜欢在第一次导入数据时进行转换。
【参考方案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() 方法不是更好吗?map
和 apply
都可以接受函数,这就是为什么这会让像你这样的用户感到困惑。我只使用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 applymap
将to_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 的方法比快速查找而不是转换。以上是关于将熊猫数据框中的多列更改为日期时间的主要内容,如果未能解决你的问题,请参考以下文章