考虑以下虚构的CSV:
from io import StringIO
data = """value,date
7,null
7,10/18/2008
621,(null)"""
fake_file = StringIO(data)
我想使用pandas.read_csv
读取此文件,使用na_values
参数处理空值,并使用parse_dates
和date_parser
处理日期:
import pandas as pd
date_parser = lambda c: pd.datetime.strptime(c, '%m/%d/%Y')
df = pd.read_csv(fake_file,
parse_dates=['date'],
date_parser=date_parser,
na_values=['null', '(null)'])
在 Python 3.5 中运行这段代码会给我这个:
File "<ipython-input-11-aa5bcf0858b7>", line 1, in <lambda>
date_parser = lambda c: pd.datetime.strptime(c, DATE_FMT)
TypeError: strptime() argument 1 must be str, not float
所以似乎首先处理空值,然后尝试解析日期......
我知道我可以这样做:
df = pd.read_csv(fake_file,
na_values=['null', '(null)'])
df['date'] = pd.to_datetime(df['date'],
format='%m/%d/%Y')
但我真正的问题是如何一举处理日期格式和NaN
处理......
将to_datetime
与format
和errors='coerce'
一起使用:
date_parser = lambda c: pd.to_datetime(c, format='%m/%d/%Y', errors='coerce')
df = pd.read_csv(fake_file, parse_dates=['date'], date_parser=date_parser)
print (df)
value date
0 7 NaT
1 7 2008-10-18
2 621 NaT
问题是您的自定义日期解析器 - 它无法处理NaN
。相反,您可以将pandas.to_datetime
函数用作解析器:
from functools import partial
date_parser = partial(pd.to_datetime, format='%m/%d/%Y')
利用infer_datetime_format=True
参数:
In [24]: pd.read_csv(StringIO(data), parse_dates=['date'], infer_datetime_format=True, na_values=['null', '(null)'])
Out[24]:
value date
0 7 NaT
1 7 2008-10-18
2 621 NaT
PS我想你的第二个选择可能会更快
默认情况下pd.to_datetime
可以处理NaN
,因此,您只需要将创建的date_parser
替换为pd.to_datetime
。
解决方案如下所示:
In [10]: pd.read_csv(pd.io.common.StringIO(data), parse_dates=['date'],
...: date_parser=pd.to_datetime, na_values=['null', '(null)'])
Out[10]:
value date
0 7 NaT
1 7 2008-10-18
2 621 NaT