繁体   English   中英

在 Pandas MultiIndex 中移动 DateTime 索引

[英]Shift DateTime index within a Pandas MultiIndex

我有一个 csv 文件,当我加载它时,它看起来像这样:

# generate example data
users = ['A', 'B', 'C', 'D']
#dates = pd.date_range("2020-02-01 00:00:00", "2020-04-04 20:00:00", freq="H")
dates = pd.date_range("2020-02-01 00:00:00", "2020-02-04 20:00:00", freq="H")
idx = pd.MultiIndex.from_product([users, dates])
idx.names = ["user", "datehour"]
y = pd.Series(np.random.choice(a=[0, 1], size=len(idx)), index=idx).rename('y')

# write to csv and reload (turns out this matters)
y.to_csv('reprod_example.csv')
y = pd.read_csv('reprod_example.csv', parse_dates=['datehour'])
y = y.set_index(['user', 'datehour']).y

>>> y.head()
user  datehour           
A     2020-02-01 00:00:00    0
      2020-02-01 01:00:00    0
      2020-02-01 02:00:00    1
      2020-02-01 03:00:00    0
      2020-02-01 04:00:00    0
Name: y, dtype: int64

我有以下 function 来创建索引级别的滞后特征:

def shift_index(a, dt_idx_name, lag_freq, lag):

    # get datetime index of relevant level
    ac = a.copy()
    dti = ac.index.get_level_values(dt_idx_name)

    # shift it
    dti_shifted = dti.shift(lag, freq=lag_freq)

    # put it back where you found it
    ac.index.set_levels(dti_shifted, level=dt_idx_name, inplace=True)

    return ac

但是当我运行: y_lag = shift_index(y, 'datehour', 'H', 1)时,我收到以下错误:

ValueError: Level values must be unique...

(我实际上可以通过在 function 中的.index.set_levels...中添加verify_integrity=False来抑制此错误,但这(可以预见)会导致问题)

这是奇怪的部分。 如果您运行上面的示例但没有从 csv 保存/重新加载,它可以工作。 我认为,原因似乎是y.index.get_level_value('datehour')在创建后立即显示freq='H'属性,但是一旦从 csv 重新加载,它就会显示freq=None属性。

这是有道理的,csv 显然不会保存该元数据。 但是我发现为 MultiIndexed 系列设置 freq 属性非常困难。 例如,这什么也没做。 df.index.freq = pd.tseries.frequencies.to_offset("H") 这个答案也不适用于我的 MultiIndex。

因此,如果我能够设置 MultiIndex 的 DateTime 组件的freq属性,我想我可以解决这个问题。 但我的最终目标是使用移位的 DateTime MultiIndex 组件创建我的y数据版本,例如上面的shift_index function。 由于我通过 csv 接收我的数据,“只是不要保存到 csv 并重新加载”不是一个选项。

经过一番烦躁之后,我能够使用asfreq('H')对分组数据设置每小时频率,这样每个组的datehour索引都有唯一的值。

y = pd.read_csv('reprod_example.csv', parse_dates=['datehour'])
y = y.groupby('user').apply(lambda df: df.set_index('datehour').asfreq('H')).y

查看索引值显示正确的频率。

y.index[0]                                                                                                                                                                                                                          
# ('A', Timestamp('2020-02-01 00:00:00', freq='H'))

所有这一切都是将索引设置为两部分。 user先走,以便嵌套的datehour索引在其中可以是唯一的。 一旦datehour索引是唯一的,那么asfreq就可以毫无困难地使用。

如果您在非唯一索引上尝试asfreq ,它将不起作用。

y_load.set_index('datehour').asfreq('H')
# ---------------------------------------------------------------------------
# ValueError                                Traceback (most recent call last)
# <ipython-input-433-3ba51b619417> in <module>
# ----> 1 y_load.set_index('datehour').asfreq('H')
# ...
# ValueError: cannot reindex from a duplicate axis

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM