Rom*_*man 127 python types date dataframe pandas
今天,我对以下事实感到非常惊讶:从数据文件中读取数据(例如)pandas能够识别值的类型:
df = pandas.read_csv('test.dat', delimiter=r"\s+", names=['col1','col2','col3'])
Run Code Online (Sandbox Code Playgroud)
例如,可以通过以下方式检查:
for i, r in df.iterrows():
print type(r['col1']), type(r['col2']), type(r['col3'])
Run Code Online (Sandbox Code Playgroud)
特别是整数,浮点数和字符串被正确识别.但是,我有一个列具有以下格式的日期:2013-6-4.这些日期被识别为字符串(而不是python日期对象).有没有办法"学习"大熊猫到公认的日期?
Rut*_*ies 279
你应该添加parse_dates=True,或者parse_dates=['column name']在阅读时,通常足以神奇地解析它.但总有奇怪的格式需要手动定义.在这种情况下,您还可以添加日期解析器功能,这是最灵活的方式.
假设你的字符串有一个'datetime'列,那么:
dateparse = lambda x: pd.datetime.strptime(x, '%Y-%m-%d %H:%M:%S')
df = pd.read_csv(infile, parse_dates=['datetime'], date_parser=dateparse)
Run Code Online (Sandbox Code Playgroud)
这样,您甚至可以将多个列组合到一个日期时间列中,这会将"日期"和"时间"列合并为一个"日期时间"列:
dateparse = lambda x: pd.datetime.strptime(x, '%Y-%m-%d %H:%M:%S')
df = pd.read_csv(infile, parse_dates={'datetime': ['date', 'time']}, date_parser=dateparse)
Run Code Online (Sandbox Code Playgroud)
你可以找到指令(即用于不同格式的字母)的strptime和strftime 在这个页面.
Sea*_*ean 18
自@Rutger回答以来,pandas接口可能已经改变,但在我使用的版本(0.15.2)中,该date_parser函数接收日期列表而不是单个值.在这种情况下,他的代码应该像这样更新:
dateparse = lambda dates: [pd.datetime.strptime(d, '%Y-%m-%d %H:%M:%S') for d in dates]
df = pd.read_csv(infile, parse_dates=['datetime'], date_parser=dateparse)
Run Code Online (Sandbox Code Playgroud)
Joo*_*oop 11
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’
Run Code Online (Sandbox Code Playgroud)
默认的日期感知效果很好,但它似乎偏向北美日期格式.如果你住在别处,你可能偶尔会被结果抓住.据我所知,2000年1月6日意味着1月6日在美国,而不是我住的6月1日.如果使用23/6/2000这样的日期,它就足够聪明地摆动它们.尽管如此,保持YYYYMMDD日期变化可能更安全.向熊猫开发者致歉,但我最近没有用本地日期测试它.
您可以使用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.
Run Code Online (Sandbox Code Playgroud)
将两列合并到一个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)
Run Code Online (Sandbox Code Playgroud)
是的 - 根据pandas.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.to_datetime()按照文档中的建议使用pandas.read_csv():
如果列或索引包含不可解析的日期,则整个列或索引将作为对象数据类型保持不变.对于非标准日期时间解析,请
pd.to_datetime在之后使用pd.read_csv.
演示:
>>> D = {'date': '2013-6-4'}
>>> df = pd.DataFrame(D, index=[0])
>>> df
date
0 2013-6-4
>>> df.dtypes
date object
dtype: object
>>> df['date'] = pd.to_datetime(df.date, format='%Y-%m-%d')
>>> df
date
0 2013-06-04
>>> df.dtypes
date datetime64[ns]
dtype: object
Run Code Online (Sandbox Code Playgroud)
作为使 Pandas 2.0 中的日期时间处理更加可靠的广泛尝试的一部分,日期解析(特别是在 CSV 文件上)出现了许多向后不兼容的更改和弃用。infer_datetime_format许多其他答案推荐的和参数date_parser现在均已弃用。
现在解析已知格式的日期的正确方法是使用 的parse_dates和date_format参数pd.read_csv()。
df = pd.read_csv(
infile,
parse_dates=['My DateTime']
)
Run Code Online (Sandbox Code Playgroud)
df = pd.read_csv(
infile,
parse_dates=['My DateTime'],
date_format={'My DateTime': '%Y-%m-%d %H:%M:%S'}
)
Run Code Online (Sandbox Code Playgroud)
df = pd.read_csv(
infile,
parse_dates={'mydatetime': ['My Date', 'My Time']},
# mydatetime will contain my_date and my_time separated by a single space
date_format={'mydatetime': '%Y-%m-%d %H:%M:%S'}
)
Run Code Online (Sandbox Code Playgroud)
如果您的日期解析逻辑比使用静态格式字符串可以完成的更复杂,例如,如果您在同一列上有多种日期格式,或者正在高级使用date_parser,则官方文档鼓励您将列保留为object读取文件时的默认类型,并在第二遍中使用 进行日期转换pd.to_datetime,如下所示。
除了其他回复所说的之外,如果您必须解析具有数十万个时间戳的非常大的文件,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')
Run Code Online (Sandbox Code Playgroud)
# 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')
Run Code Online (Sandbox Code Playgroud)
# 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])
Run Code Online (Sandbox Code Playgroud)
对于我的 200k 行文件(每行一个时间戳)的用例,这将处理时间从大约一分钟减少到不到一秒。
| 归档时间: |
|
| 查看次数: |
162259 次 |
| 最近记录: |