python - 使用 Pandas 读取 csv 时间数据时数据类型不一致
问题描述
我正在使用 Pandas 读取带有时间数据的 csv 文件。我注意到时间戳的数据格式因时区而异。我不是这里的专家,所以也许我犯了一个错误。这是一个最小的例子来说明我的意思。
我有两个 csv 文件:data1.csv:
Timestamp,State
2020-05-26T10:00:00+01:00,3
2020-05-26T10:10:00+00:00,1
和data2.csv:
Timestamp,State
2020-05-26T10:00:00+00:00,3
2020-05-26T10:10:00+00:00,1
请注意,唯一的区别是第一行中的时区。当我读取第一个 csv 文件时,我得到了 Python 日期时间的时间戳(请注意,我只查看在两种情况下时间戳相同的最后一行):
In [1]: import pandas as pd
In [2]: df_1 = pd.read_csv('data1.csv', parse_dates=['Timestamp'])
In [3]: df_1['Timestamp'].values[1]
Out[3]: datetime.datetime(2020, 5, 26, 10, 10, tzinfo=tzutc())
In [4]: df_1.iloc[1].Timestamp
Out[4]: datetime.datetime(2020, 5, 26, 10, 10, tzinfo=tzutc())
所以这很好。但是,当我对 data2.csv 执行相同操作时,我得到
In [5]: df_2 = pd.read_csv('data2.csv', parse_dates=['Timestamp'])
In [6]: df_2['Timestamp'].values[1]
Out[6]: numpy.datetime64('2020-05-26T10:10:00.000000000')
In [7]: df_2.iloc[1].Timestamp
Out[7]: Timestamp('2020-05-26 10:10:00+0000', tz='UTC')
所以现在我们有时间戳作为 Numpy datetime64 或 Timestamps,这取决于我们如何从 DataFrame 中提取它们。
格式不一致很烦人。这是一个错误还是我做错了什么?
解决方案
这是 pandas 的一个弱点:它不能原生地表示具有混合时区的列。有关详细信息,请参阅
https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-csv-mixed-timezones。与那里写的相反,我得到了混合时区列的 pythondatetime
类型(不是string
),但是它应该回答你的问题。
import pandas as pd
import io
print(pd.__version__)
s1 = """Timestamp,State
2020-05-26T10:00:00+01:00,3
2020-05-26T10:10:00+00:00,1"""
s2 = """Timestamp,State
2020-05-26T10:00:00+00:00,3
2020-05-26T10:10:00+00:00,1"""
print('\n----- default:')
df1 = pd.read_csv(io.StringIO(s1), parse_dates=['Timestamp'])
print(df1, '\n', df1.applymap(type))
df2 = pd.read_csv(io.StringIO(s2), parse_dates=['Timestamp'])
print(df2, '\n', df2.applymap(type))
print('\n----- with date_parser:')
df1 = pd.read_csv(io.StringIO(s1), parse_dates=['Timestamp'], date_parser=lambda col: pd.to_datetime(col, utc=True))
print(df1, '\n', df1.applymap(type))
df2 = pd.read_csv(io.StringIO(s2), parse_dates=['Timestamp'], date_parser=lambda col: pd.to_datetime(col, utc=True))
print(df2, '\n', df2.applymap(type))
输出:
1.0.3
----- default:
Timestamp State
0 2020-05-26 10:00:00+01:00 3
1 2020-05-26 10:10:00+00:00 1
Timestamp State
0 <class 'datetime.datetime'> <class 'int'>
1 <class 'datetime.datetime'> <class 'int'>
Timestamp State
0 2020-05-26 10:00:00+00:00 3
1 2020-05-26 10:10:00+00:00 1
Timestamp State
0 <class 'pandas._libs.tslibs.timestamps.Timesta... <class 'int'>
1 <class 'pandas._libs.tslibs.timestamps.Timesta... <class 'int'>
----- with date_parser:
Timestamp State
0 2020-05-26 09:00:00+00:00 3
1 2020-05-26 10:10:00+00:00 1
Timestamp State
0 <class 'pandas._libs.tslibs.timestamps.Timesta... <class 'int'>
1 <class 'pandas._libs.tslibs.timestamps.Timesta... <class 'int'>
Timestamp State
0 2020-05-26 10:00:00+00:00 3
1 2020-05-26 10:10:00+00:00 1
Timestamp State
0 <class 'pandas._libs.tslibs.timestamps.Timesta... <class 'int'>
1 <class 'pandas._libs.tslibs.timestamps.Timesta... <class 'int'>
推荐阅读
- javascript - Html5 有一个动画画布作为 Div 元素的背景?
- html - Flex-direction 列在 Internet Explorer 11 中不起作用
- little-man-computer - 冒泡排序 4 个数字
- flutter - Dart/Flutter 中的 Spotify PKCE:“code_verifier 不正确”
- javascript - 在 CSS 过渡过程中实时获取高度值
- regex - 我想读取文件并使用 AWK 存储一些变量
- markdown - 带有 bookdown 的 Markdown HTML:更改图形编号
- laravel - 当新项目被放置在 Laravel 应用程序的 composer.json 文件中时会发生什么
- python - 为什么要创建一个方法类型的对象,我想要一个列表类型的对象
- r - 如何将 R 输出保存在不同的目录中?