今天,我非常惊讶地发现,当从数据文件读取数据时(例如),熊猫能够识别值的类型:

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)。


当前回答

是的——根据熊猫的说法。read_csv文档:

注意:对于iso8601格式的日期存在快速路径。

因此,如果您的csv有一个名为datetime的列,日期看起来像2013-01-01T01:01,例如,运行这个将使pandas(我在v0.19.2)自动获取日期和时间:

Df = pd.read_csv('test.csv', parse_dates=['datetime'])

请注意,您需要显式地传递parse_dates,否则它无法工作。

验证:

df.dtypes

您应该看到该列的数据类型是datetime64[ns]

其他回答

Pandas read_csv方法非常适合解析日期。完整的文档请访问http://pandas.pydata.org/pandas-docs/stable/generated/pandas.io.parsers.read_csv.html

你甚至可以在不同的列中有不同的日期部分,并传递参数:

parse_dates : boolean, list of ints or names, list of lists, or dict
If True -> try parsing the index. If [1, 2, 3] -> try parsing columns 1, 2, 3 each as a
separate date column. If [[1, 3]] -> combine columns 1 and 3 and parse as a single date
column. {‘foo’ : [1, 3]} -> parse columns 1, 3 as date and call result ‘foo’

The default sensing of dates works great, but it seems to be biased towards north american Date formats. If you live elsewhere you might occasionally be caught by the results. As far as I can remember 1/6/2000 means 6 January in the USA as opposed to 1 Jun where I live. It is smart enough to swing them around if dates like 23/6/2000 are used. Probably safer to stay with YYYYMMDD variations of date though. Apologies to pandas developers,here but i have not tested it with local dates recently.

可以使用date_parser参数传递一个函数来转换格式。

date_parser : function
Function to use for converting a sequence of string columns to an array of datetime
instances. The default uses dateutil.parser.parser to do the conversion.

你应该在读取时添加parse_dates=True,或者parse_dates=['列名'],这通常足以神奇地解析它。但是总有一些奇怪的格式需要手动定义。在这种情况下,还可以添加日期解析器函数,这是最灵活的方法。

假设你的字符串有一个列'datetime',那么:

from datetime import datetime
dateparse = lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M:%S')

df = pd.read_csv(infile, parse_dates=['datetime'], date_parser=dateparse)

通过这种方式,你甚至可以将多个列合并到一个datetime列中,这将'date'和'time'列合并到一个'datetime'列中:

dateparse = lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M:%S')

df = pd.read_csv(infile, parse_dates={'datetime': ['date', 'time']}, date_parser=dateparse)

你可以在本页找到strptime和strftime的指令(即用于不同格式的字母)。

是的——根据熊猫的说法。read_csv文档:

注意:对于iso8601格式的日期存在快速路径。

因此,如果您的csv有一个名为datetime的列,日期看起来像2013-01-01T01:01,例如,运行这个将使pandas(我在v0.19.2)自动获取日期和时间:

Df = pd.read_csv('test.csv', parse_dates=['datetime'])

请注意,您需要显式地传递parse_dates,否则它无法工作。

验证:

df.dtypes

您应该看到该列的数据类型是datetime64[ns]

当将两个列合并为单个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)

除了其他回复所说的,如果必须解析具有数十万个时间戳的非常大的文件,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行(每行一个时间戳),这将处理时间从大约一分钟缩短到不到一秒。