python 如何从pandas中的Timestamp列中删除时区

omqzjyyz  于 2023-11-15  发布在  Python
关注(0)|答案(4)|浏览(81)

我读Pandas change timezone for forex DataFrame,但我想让我的recrame timezone的time列与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


我该怎么做才能用一个简单的时区时间戳来替换列呢?

mzsu5hc0

mzsu5hc01#

列必须是datetime dtype,例如在使用pd.to_datetime之后。然后,您可以使用tz_localize来更改时区,一个朴素的时间戳对应于时区None

testdata['time'].dt.tz_localize(None)

字符串
除非列是索引(DatetimeIndex),否则必须使用.dt访问器来访问pandas datetime functions

eagi6jfj

eagi6jfj2#

当您的数据包含跨越不同时区或应用夏令时之前和之后的日期时间时,例如使用psycopg 2从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
cgvd09ve

cgvd09ve3#

我知道你提到你的时间戳已经是UTC了,但是为了防御起见,你也可以让你的代码不受时间戳(部分或全部)在不同时区的情况的影响。这不会花费任何东西,而且会更健壮:

newcol = testdata['time'].dt.tz_convert(None)

字符串
per the docs
Nonetz将转换为UTC并删除时区信息。
这比删除时间戳可能包含的任何时区更安全。

rqcrx0a6

rqcrx0a64#

这里有一个函数,

  • 查找包含任何pd.Timestamp示例的所有列
  • 将这些列转换为dtype datetime(以便能够在Series上使用.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

字符串

相关问题