Pandas中read_csv函数中的datetime数据类型

237

我正在读取一个包含多个日期时间列的csv文件。在读取文件时,我需要设置数据类型,但是日期时间似乎是一个问题。例如:

headers = ['col1', 'col2', 'col3', 'col4']
dtypes = ['datetime', 'datetime', 'str', 'float']
pd.read_csv(file, sep='\t', header=None, names=headers, dtype=dtypes)

当运行时出现错误:
类型错误:数据类型“datetime”不被理解
通过 pandas.to_datetime() 后期转换列不是我能选择的选项。我无法知道哪些列将成为 datetime 对象,这个信息可能会发生改变并且来自于确定我的 dtypes 列表的任何来源。
作为替代方案,我尝试使用 numpy.genfromtxt 加载 csv 文件,设置该函数中的 dtypes,然后将其转换为 pandas.dataframe,但它会破坏数据。非常感谢您的帮助!
6个回答

422

为什么它不起作用

read_csv 中没有 datetime dtype 可以设置,因为 csv 文件只能包含字符串、整数和浮点数。

将 dtype 设置为 datetime 将使 pandas 将 datetime 解释为对象,这意味着您最终会得到一个字符串。

Pandas 解决方法

pandas.read_csv() 函数有一个关键字参数叫做 parse_dates

使用此参数,您可以即时将字符串、浮点数或整数转换为 datetime,使用默认的 date_parser (dateutil.parser.parser)

headers = ['col1', 'col2', 'col3', 'col4']
dtypes = {'col1': 'str', 'col2': 'str', 'col3': 'str', 'col4': 'float'}
parse_dates = ['col1', 'col2']
pd.read_csv(file, sep='\t', header=None, names=headers, dtype=dtypes, parse_dates=parse_dates)

这将导致pandas将col1col2读取为字符串,它们很可能是字符串(例如"2016-05-05"),在读取字符串后,每个列的日期解析器将对该字符串进行操作,并返回该函数返回的任何内容。
定义自己的日期解析函数: pandas.read_csv() 函数还有一个关键字参数叫做 date_parser。将其设置为 lambda 函数将使该特定函数用于解析日期。
注意事项:
必须提供函数而不是执行函数,因此以下写法是正确的。
date_parser = pd.datetools.to_datetime

这是不正确的

date_parser = pd.datetools.to_datetime()

Pandas 0.22 更新

pd.datetools.to_datetime 已被移动到 date_parser = pd.to_datetime

感谢 @stackoverYC


1
@Drake 我认为用户3221055从未回到过该网站。这就是问题所在。个人资料上显示“最后出现于2014年5月20日2:35”。 - firelynx
2
这是一个慢速的解决方案。请查看此链接代替:https://dev59.com/T10a5IYBdhLWcg3w07zt - Reddspark
@user1761806 嘿,不错的发现!不过我做了一个更好的。https://dev59.com/T10a5IYBdhLWcg3w07zt#46183514 - firelynx
2
在pandas 0.22.0中,pandas.core.datetools.to_datetime已被弃用,请改用pd.datetools.to_datetime。例如:date_parser = pd.to_datetime - stackoverYC
2
还有一个converters参数,您可以在其中指定哪些列具有哪些转换器。parse_dates很有帮助,可以处理坏数据,但由于它测试和推断每个值,因此速度较慢。https://gist.github.com/gjreda/7433f5f70299610d9b6b - Davos
如果您的文件已经有标题,请不要忘记添加 skiprows=1 - d_-

71

read_csv中有一个parse_dates参数,它允许您定义要作为日期或日期时间处理的列的名称:

date_cols = ['col1', 'col2']
pd.read_csv(file, sep='\t', header=None, names=headers, parse_dates=date_cols)

3
之前我传递了单个字符串列名出现了错误,现在我明白了即使只有一个值也需要传递一个列表。 - TapanHP
如何在使用parse_dates解析日期列的同时,使用dtype定义非日期列? - James

23
你可以尝试传递实际数据类型,而非字符串。
import pandas as pd
from datetime import datetime
headers = ['col1', 'col2', 'col3', 'col4'] 
dtypes = [datetime, datetime, str, float] 
pd.read_csv(file, sep='\t', header=None, names=headers, dtype=dtypes)

但是如果没有您的数据进行调试,这将非常难以诊断。

实际上,您可能需要使用pandas将日期解析为时间戳,如下所示:

pd.read_csv(file, sep='\t', header=None, names=headers, parse_dates=True)

7
我使用了以下代码,它可以正常运行:
headers = ['col1', 'col2', 'col3', 'col4']
df=pd.read_csv(file, sep='\t', header=None, names=headers, parse_dates=['col1', 'col2'])

2
添加上下文会帮助其他用户更好地理解您的答案。 - Jimit Vaghela
是的,但这是否强制 col3-str 和 col4=float? - James

7

我的解决方法是将其加载为默认类型,然后在下一行使用pandas.to_datetime()函数。

df[target_col] = pd.to_datetime(df[target_col])

0
我尝试使用dtypes=[datetime, ...]选项,但是...
import pandas as pd
from datetime import datetime
headers = ['col1', 'col2', 'col3', 'col4'] 
dtypes = [datetime, datetime, str, float] 
pd.read_csv(file, sep='\t', header=None, names=headers, dtype=dtypes)

我遇到了以下错误:

TypeError: data type not understood

我唯一需要做的更改是将datetime替换为datetime.datetime

import pandas as pd
from datetime import datetime
headers = ['col1', 'col2', 'col3', 'col4'] 
dtypes = [datetime.datetime, datetime.datetime, str, float] 
pd.read_csv(file, sep='\t', header=None, names=headers, dtype=dtypes)

4
这仍然会使得结果数据框的dtype为object,而不是pandas.datetime。 - firelynx
20
除了这样做没有所期望的效果外,它也不起作用:AttributeError: type object 'datetime.datetime' has no attribute 'datetime' - Gabriel

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