如何从 pandas 数据帧的时间戳列中删除时区
How to remove timezone from a Timestamp column in a pandas dataframe
我读过 但我想让我的数据帧时区的时间列天真以便与 sqlite3 数据库进行互操作。
我的 pandas 数据框中的数据已经转换为 UTC 数据,但我不想在数据库中维护这个 UTC 时区信息。
给定从其他来源导出的数据样本,它看起来像这样:
print(type(testdata))
print(testdata)
print(testdata.applymap(type))
给出:
<class 'pandas.core.frame.DataFrame'>
time navd88_ft station_id new
0 2018-03-07 01:31:02+00:00 -0.030332 13 5
1 2018-03-07 01:21:02+00:00 -0.121653 13 5
2 2018-03-07 01:26:02+00:00 -0.072945 13 5
3 2018-03-07 01:16:02+00:00 -0.139917 13 5
4 2018-03-07 01:11:02+00:00 -0.152085 13 5
time navd88_ft station_id \
0 <class 'pandas._libs.tslib.Timestamp'> <class 'float'> <class 'int'>
1 <class 'pandas._libs.tslib.Timestamp'> <class 'float'> <class 'int'>
2 <class 'pandas._libs.tslib.Timestamp'> <class 'float'> <class 'int'>
3 <class 'pandas._libs.tslib.Timestamp'> <class 'float'> <class 'int'>
4 <class 'pandas._libs.tslib.Timestamp'> <class 'float'> <class 'int'>
new
0 <class 'int'>
1 <class 'int'>
2 <class 'int'>
3 <class 'int'>
4 <class 'int'>
但是
newstamp = testdata['time'].tz_convert(None)
给出最终错误:
TypeError: index is not a valid DatetimeIndex or PeriodIndex
我该怎么做才能用时区原始时间戳替换该列?
该列必须是 datetime
dtype,例如在使用 pd.to_datetime
之后。
然后,您可以使用 tz_localize
更改时区,一个天真的时间戳对应时区 None
:
testdata['time'].dt.tz_localize(None)
除非列是索引 (DatetimeIndex
), the .dt
accessor must be used to access pandas datetime functions.
当您的数据包含跨越不同时区或应用夏令时前后的日期时间时,例如使用 psycopg2 从 postges 数据库获取,根据 pandas 版本,您可能最终会遇到一些最佳转换方法的场景:
testdata['time'].apply(lambda x: x.replace(tzinfo=None))
此方法有效的情况(注意 FixedOffsetTimezone
与不同 offset
的用法)而 .dt.tz_localize(None)
的用法无效:
df = pd.DataFrame([
datetime.datetime(2018, 5, 17, 21, 40, 20, 775854,
tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=120, name=None)),
datetime.datetime(2021, 3, 17, 14, 36, 13, 902741,
tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=60, name=None))
])
pd.__version__
'0.24.2'
df[0].dt.tz_localize(None)
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/pandas/core/arrays/datetimes.py", line 1861, in objects_to_datetime64ns
values, tz_parsed = conversion.datetime_to_datetime64(data)
File "pandas/_libs/tslibs/conversion.pyx", line 185, in pandas._libs.tslibs.conversion.datetime_to_datetime64
ValueError: Array must be all same time zone
pd.__version__
'1.1.2'
df[0].dt.tz_localize(None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.8/site-packages/pandas/core/generic.py", line 5132, in __getattr__
return object.__getattribute__(self, name)
File "/usr/local/lib/python3.8/site-packages/pandas/core/accessor.py", line 187, in __get__
accessor_obj = self._accessor(obj)
File "/usr/local/lib/python3.8/site-packages/pandas/core/indexes/accessors.py", line 480, in __new__
raise AttributeError("Can only use .dt accessor with datetimelike values")
AttributeError: Can only use .dt accessor with datetimelike values
我知道您提到您的时间戳已经在 UTC 中,但为了防御起见,您不妨让您的代码不受时间戳(部分或全部)处于不同时区的情况的影响。这不需要任何成本,而且会更健壮:
newcol = testdata['time'].dt.tz_convert(None)
作为per the docs:
A tz
of None
will convert to UTC and remove the timezone information.
这比只删除时间戳可能包含的任何时区更安全。
这是一个函数
- 查找其中包含任何 pd.Timestamp 实例的所有列
- 将这些列转换为 dtype datetime(以便能够在系列中使用 .dt 访问器)
- 使用
dt.tz_localize(None)
本地化所有时间戳,这将保持相对于 UTC 的时移
def remove_tz_from_dataframe(df_in):
df = df_in.copy()
col_times = [ col for col in df.columns if any([isinstance(x, pd.Timestamp for x in df[col]])]
for col in col_times:
df[col] = pd.to_datetime(
df[col], infer_datetime_format=True)
df[col] = df[col].dt.tz_localize(None)
return df
我读过
我的 pandas 数据框中的数据已经转换为 UTC 数据,但我不想在数据库中维护这个 UTC 时区信息。
给定从其他来源导出的数据样本,它看起来像这样:
print(type(testdata))
print(testdata)
print(testdata.applymap(type))
给出:
<class 'pandas.core.frame.DataFrame'>
time navd88_ft station_id new
0 2018-03-07 01:31:02+00:00 -0.030332 13 5
1 2018-03-07 01:21:02+00:00 -0.121653 13 5
2 2018-03-07 01:26:02+00:00 -0.072945 13 5
3 2018-03-07 01:16:02+00:00 -0.139917 13 5
4 2018-03-07 01:11:02+00:00 -0.152085 13 5
time navd88_ft station_id \
0 <class 'pandas._libs.tslib.Timestamp'> <class 'float'> <class 'int'>
1 <class 'pandas._libs.tslib.Timestamp'> <class 'float'> <class 'int'>
2 <class 'pandas._libs.tslib.Timestamp'> <class 'float'> <class 'int'>
3 <class 'pandas._libs.tslib.Timestamp'> <class 'float'> <class 'int'>
4 <class 'pandas._libs.tslib.Timestamp'> <class 'float'> <class 'int'>
new
0 <class 'int'>
1 <class 'int'>
2 <class 'int'>
3 <class 'int'>
4 <class 'int'>
但是
newstamp = testdata['time'].tz_convert(None)
给出最终错误:
TypeError: index is not a valid DatetimeIndex or PeriodIndex
我该怎么做才能用时区原始时间戳替换该列?
该列必须是 datetime
dtype,例如在使用 pd.to_datetime
之后。
然后,您可以使用 tz_localize
更改时区,一个天真的时间戳对应时区 None
:
testdata['time'].dt.tz_localize(None)
除非列是索引 (DatetimeIndex
), the .dt
accessor must be used to access pandas datetime functions.
当您的数据包含跨越不同时区或应用夏令时前后的日期时间时,例如使用 psycopg2 从 postges 数据库获取,根据 pandas 版本,您可能最终会遇到一些最佳转换方法的场景:
testdata['time'].apply(lambda x: x.replace(tzinfo=None))
此方法有效的情况(注意 FixedOffsetTimezone
与不同 offset
的用法)而 .dt.tz_localize(None)
的用法无效:
df = pd.DataFrame([
datetime.datetime(2018, 5, 17, 21, 40, 20, 775854,
tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=120, name=None)),
datetime.datetime(2021, 3, 17, 14, 36, 13, 902741,
tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=60, name=None))
])
pd.__version__
'0.24.2'
df[0].dt.tz_localize(None)
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/pandas/core/arrays/datetimes.py", line 1861, in objects_to_datetime64ns
values, tz_parsed = conversion.datetime_to_datetime64(data)
File "pandas/_libs/tslibs/conversion.pyx", line 185, in pandas._libs.tslibs.conversion.datetime_to_datetime64
ValueError: Array must be all same time zone
pd.__version__
'1.1.2'
df[0].dt.tz_localize(None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.8/site-packages/pandas/core/generic.py", line 5132, in __getattr__
return object.__getattribute__(self, name)
File "/usr/local/lib/python3.8/site-packages/pandas/core/accessor.py", line 187, in __get__
accessor_obj = self._accessor(obj)
File "/usr/local/lib/python3.8/site-packages/pandas/core/indexes/accessors.py", line 480, in __new__
raise AttributeError("Can only use .dt accessor with datetimelike values")
AttributeError: Can only use .dt accessor with datetimelike values
我知道您提到您的时间戳已经在 UTC 中,但为了防御起见,您不妨让您的代码不受时间戳(部分或全部)处于不同时区的情况的影响。这不需要任何成本,而且会更健壮:
newcol = testdata['time'].dt.tz_convert(None)
作为per the docs:
A
tz
ofNone
will convert to UTC and remove the timezone information.
这比只删除时间戳可能包含的任何时区更安全。
这是一个函数
- 查找其中包含任何 pd.Timestamp 实例的所有列
- 将这些列转换为 dtype datetime(以便能够在系列中使用 .dt 访问器)
- 使用
dt.tz_localize(None)
本地化所有时间戳,这将保持相对于 UTC 的时移
def remove_tz_from_dataframe(df_in):
df = df_in.copy()
col_times = [ col for col in df.columns if any([isinstance(x, pd.Timestamp for x in df[col]])]
for col in col_times:
df[col] = pd.to_datetime(
df[col], infer_datetime_format=True)
df[col] = df[col].dt.tz_localize(None)
return df