今天,我非常惊讶地发现,当从数据文件读取数据时(例如),熊猫能够识别值的类型:
df = pandas.read_csv('test.dat', delimiter=r"\s+", names=['col1','col2','col3'])
例如,可以这样检查:
for i, r in df.iterrows():
print type(r['col1']), type(r['col2']), type(r['col3'])
特别是整数、浮点数和字符串被正确识别。但是,我有一列的日期格式如下:2013-6-4。这些日期被识别为字符串(而不是python date-objects)。
当将两个列合并为单个datetime列时,接受的答案将生成一个错误(pandas版本0.20.3),因为列分别发送给date_parser函数。
以下工作:
def dateparse(d,t):
dt = d + " " + t
return pd.datetime.strptime(dt, '%d/%m/%Y %H:%M:%S')
df = pd.read_csv(infile, parse_dates={'datetime': ['date', 'time']}, date_parser=dateparse)
也许自从@Rutger回答之后,pandas接口已经改变了,但在我使用的版本(0.15.2)中,date_parser函数接收的是日期列表,而不是单个值。在这种情况下,他的代码应该像这样更新:
from datetime import datetime
import pandas as pd
dateparse = lambda dates: [datetime.strptime(d, '%Y-%m-%d %H:%M:%S') for d in dates]
df = pd.read_csv('test.dat', parse_dates=['datetime'], date_parser=dateparse)
由于最初的提问者说他想要日期,而日期是2013-6-4格式,dateparse函数应该是:
dateparse = lambda dates: [datetime.strptime(d, '%Y-%m-%d').date() for d in dates]
除了其他回复所说的,如果必须解析具有数十万个时间戳的非常大的文件,date_parser可能会成为一个巨大的性能瓶颈,因为它是一个每行调用一次的Python函数。您可以通过在解析CSV文件时将日期保存为文本,然后将整个列一次性转换为日期来获得相当大的性能改进:
# For a data column
df = pd.read_csv(infile, parse_dates={'mydatetime': ['date', 'time']})
df['mydatetime'] = pd.to_datetime(df['mydatetime'], exact=True, cache=True, format='%Y-%m-%d %H:%M:%S')
# For a DateTimeIndex
df = pd.read_csv(infile, parse_dates={'mydatetime': ['date', 'time']}, index_col='mydatetime')
df.index = pd.to_datetime(df.index, exact=True, cache=True, format='%Y-%m-%d %H:%M:%S')
# For a MultiIndex
df = pd.read_csv(infile, parse_dates={'mydatetime': ['date', 'time']}, index_col=['mydatetime', 'num'])
idx_mydatetime = df.index.get_level_values(0)
idx_num = df.index.get_level_values(1)
idx_mydatetime = pd.to_datetime(idx_mydatetime, exact=True, cache=True, format='%Y-%m-%d %H:%M:%S')
df.index = pd.MultiIndex.from_arrays([idx_mydatetime, idx_num])
在我的用例中,一个文件有200k行(每行一个时间戳),这将处理时间从大约一分钟缩短到不到一秒。