Pandas 使用时区感知索引将行插入到数据框中
Pandas insert row into dataframe with timezone-aware index
我有一个具有时区感知索引的数据框,当我尝试向该数据框插入新行时,它不起作用,而是将索引类型更改为 'object'
(即,它不能将行添加到当前类型中)。
MRE 以下:
import pandas as pd
df = pd.DataFrame({"time": ["2021/06/06 12:00:00"], "col1": [2]})
df.index = pd.to_datetime(df['time'])
df = df.drop('time', axis=1)
df.index = df.index.tz_localize('UTC')
# Doesn't work, index is now 'object' as this is considered a string
# row = pd.Series(name='2021/06/05 12:00:00')
# df = df.append(row)
# Also doesn't work, as timezones differ
row = pd.Series(name=pd.Timestamp('2021/06/05 12:00:00'))
df = df.append(row)
print(df.index)
我知道我可以做到以下几点:
tz = df.index[0].tz
row = pd.Series(name=pd.Timestamp('2021/06/05 12:00:00', tz=tz))
但是我怀疑当单位不同时这是否有效,或者甚至可能是我不知道的 pandas Timestamp
的其他 属性,所以理想情况下,我想将索引的 Timestamp
配置完全复制到我插入的新时间戳中。
如果有人碰巧知道如何在保持索引类型不变的情况下向该数据框中插入新行,我们将不胜感激。
Timestamp
对象肯定是 'object'
类型,如果您使用 Timestamp
s 作为索引,则可能无法转义索引以采用此类型。
通过“时间戳配置”,我理解为“时区”,并且您想在同一时区中插入新时间。
要么您从一开始就知道时区,并且所有行的数据都来自已知来自同一时区的来源。在这种情况下,您可以在实例化 Timestamp
s.
时指定相同的时区
或者您首先不知道数据的时区,并且您有来自另一个来源的新数据,因此可能来自您当然知道的不同时区。混合来自不同时区的时间戳不是问题,因为在将它们相互比较时应该考虑时区。您仍然可以稍后将它们全部本地化到您喜欢的时区。
因为 DatetimeTZ
only supports a single timezone, the key is to make sure the new Timestamp
始终匹配您现有的 df.index.tz
。
插入新的Timestamp
时:
- 如果来自同一时区则使用
tz=df.index.tz
- 如果来自不同时区,则使用
astimezone(df.index.tz)
例子
鉴于你的 MRE df
:
df
# col1
# time
# 2021-06-06 12:00:00+00:00 2
df.index.dtype
# datetime64[ns, UTC]
如果你知道你的新 Timestamp
在同一个 tz
中,只需像你提到的那样在构造函数中设置它:
ts1 = pd.Timestamp('2021/06/05 12:00:00', tz=df.index.tz)
df.loc[ts1] = 4
# col1
# time
# 2021-06-06 12:00:00+00:00 2
# 2021-06-05 12:00:00+00:00 4
df.index.dtype
# datetime64[ns, UTC]
如果您的新 Timestamp
在不同的 tz
中(这是您主要关心的),请使用 astimezone
[= 进行转换63=](例如,从美国东部回到 UTC):
ts2 = pd.Timestamp('2021/06/05 12:00:00', tz='US/Eastern').astimezone(df.index.tz)
df.loc[ts2] = 6
# col1
# time
# 2021-06-06 12:00:00+00:00 2
# 2021-06-05 12:00:00+00:00 4
# 2021-06-05 16:00:00+00:00 6
df.index.dtype
# datetime64[ns, UTC]
请注意,我使用的 loc
because it's faster and simpler, but append
仍然有效:
ts3 = pd.Timestamp('2021/06/05 12:00:00', tz='US/Central').astimezone(df.index.tz)
row = pd.Series([8], name=ts3, index=['col1'])
df = df.append(row)
# col1
# time
# 2021-06-06 12:00:00+00:00 2
# 2021-06-05 12:00:00+00:00 4
# 2021-06-05 16:00:00+00:00 6
# 2021-06-05 17:00:00+00:00 8
df.index.dtype
# datetime64[ns, UTC]
你也可以这样做。 DateTimeIndexes
是对象。
for time_zone in ['MST', 'EST', 'GMT']:
row = pd.Timestamp('2021/06/05 12:00:00', tz=time_zone)
df.loc[row] = 1
# to whichever timezone you want
df.index = pd.to_datetime(df.index, utc=True).tz_convert('EST')
我有一个具有时区感知索引的数据框,当我尝试向该数据框插入新行时,它不起作用,而是将索引类型更改为 'object'
(即,它不能将行添加到当前类型中)。
MRE 以下:
import pandas as pd
df = pd.DataFrame({"time": ["2021/06/06 12:00:00"], "col1": [2]})
df.index = pd.to_datetime(df['time'])
df = df.drop('time', axis=1)
df.index = df.index.tz_localize('UTC')
# Doesn't work, index is now 'object' as this is considered a string
# row = pd.Series(name='2021/06/05 12:00:00')
# df = df.append(row)
# Also doesn't work, as timezones differ
row = pd.Series(name=pd.Timestamp('2021/06/05 12:00:00'))
df = df.append(row)
print(df.index)
我知道我可以做到以下几点:
tz = df.index[0].tz
row = pd.Series(name=pd.Timestamp('2021/06/05 12:00:00', tz=tz))
但是我怀疑当单位不同时这是否有效,或者甚至可能是我不知道的 pandas Timestamp
的其他 属性,所以理想情况下,我想将索引的 Timestamp
配置完全复制到我插入的新时间戳中。
如果有人碰巧知道如何在保持索引类型不变的情况下向该数据框中插入新行,我们将不胜感激。
Timestamp
对象肯定是 'object'
类型,如果您使用 Timestamp
s 作为索引,则可能无法转义索引以采用此类型。
通过“时间戳配置”,我理解为“时区”,并且您想在同一时区中插入新时间。
要么您从一开始就知道时区,并且所有行的数据都来自已知来自同一时区的来源。在这种情况下,您可以在实例化
时指定相同的时区Timestamp
s.或者您首先不知道数据的时区,并且您有来自另一个来源的新数据,因此可能来自您当然知道的不同时区。混合来自不同时区的时间戳不是问题,因为在将它们相互比较时应该考虑时区。您仍然可以稍后将它们全部本地化到您喜欢的时区。
因为 DatetimeTZ
only supports a single timezone, the key is to make sure the new Timestamp
始终匹配您现有的 df.index.tz
。
插入新的Timestamp
时:
- 如果来自同一时区则使用
tz=df.index.tz
- 如果来自不同时区,则使用
astimezone(df.index.tz)
例子
鉴于你的 MRE
df
:df # col1 # time # 2021-06-06 12:00:00+00:00 2 df.index.dtype # datetime64[ns, UTC]
如果你知道你的新
Timestamp
在同一个tz
中,只需像你提到的那样在构造函数中设置它:ts1 = pd.Timestamp('2021/06/05 12:00:00', tz=df.index.tz) df.loc[ts1] = 4 # col1 # time # 2021-06-06 12:00:00+00:00 2 # 2021-06-05 12:00:00+00:00 4 df.index.dtype # datetime64[ns, UTC]
如果您的新
Timestamp
在不同的tz
中(这是您主要关心的),请使用astimezone
[= 进行转换63=](例如,从美国东部回到 UTC):ts2 = pd.Timestamp('2021/06/05 12:00:00', tz='US/Eastern').astimezone(df.index.tz) df.loc[ts2] = 6 # col1 # time # 2021-06-06 12:00:00+00:00 2 # 2021-06-05 12:00:00+00:00 4 # 2021-06-05 16:00:00+00:00 6 df.index.dtype # datetime64[ns, UTC]
请注意,我使用的
loc
because it's faster and simpler, butappend
仍然有效:ts3 = pd.Timestamp('2021/06/05 12:00:00', tz='US/Central').astimezone(df.index.tz) row = pd.Series([8], name=ts3, index=['col1']) df = df.append(row) # col1 # time # 2021-06-06 12:00:00+00:00 2 # 2021-06-05 12:00:00+00:00 4 # 2021-06-05 16:00:00+00:00 6 # 2021-06-05 17:00:00+00:00 8 df.index.dtype # datetime64[ns, UTC]
你也可以这样做。 DateTimeIndexes
是对象。
for time_zone in ['MST', 'EST', 'GMT']:
row = pd.Timestamp('2021/06/05 12:00:00', tz=time_zone)
df.loc[row] = 1
# to whichever timezone you want
df.index = pd.to_datetime(df.index, utc=True).tz_convert('EST')