如何使用修改后的索引来透视 Pandas 数据框?

3

I have a timeseries dataframe of the form:

rng = pd.date_range('1/1/2013', periods=1000, freq='10min')
ts = pd.Series(np.random.randn(len(rng)), index=rng)
ts = ts.to_frame(name=None)

我需要做两件事情:

步骤1:修改索引,使每天从前一天的17:00:00开始。我使用以下方法完成此操作:

ts.index = pd.to_datetime(ts.index.values + np.where((ts.index.time >= datetime.time(17)), pd.offsets.Day(1).nanos, 0))

步骤2:像这样旋转数据框:

ts_ = pd.pivot_table(ts, index=ts.index.date, columns=ts.index.time, values=0)

我遇到的问题是,在对数据框进行透视时,Pandas好像忘记了我在步骤1中所做的索引修改。
以下是示例内容:
             00:00:00    00:10:00    00:20:00   ...  23:50:00
2013-01-10  -1.800381   -0.459226   -0.172929   ... -1.000381
2013-01-11  -1.258317   -0.973924    0.955224   ...  0.072929
2013-01-12  -0.834976    0.018793   -0.141608   ...  2.072929
2013-01-13  -0.131197    0.289998    2.200644   ...  1.589998
2013-01-14  -0.991653    0.276874   -1.390654   ... -2.090654

相反,这是期望的结果。

             17:00:00    17:10:00    17:20:00   ...  16:50:00
2013-01-10  -2.800381    1.000226    2.172929   ...  0.172929
2013-01-11   0.312587    1.003924    2.556624   ... -0.556624
2013-01-12   2.976834    1.000003   -2.141608   ... -1.141608
2013-01-13   1.197131    1.333998   -2.999944   ... -1.999944
2013-01-14  -1.653991    1.278884   -1.390654   ... -4.390654
编辑 - 澄清说明: 请注意,每天开始于“17:00:00”结束于“16:50:00”。
使用Python 2.7 注意: Nickil Maveli 提出的解决方案近似正确,但是日期偏移方向不对。理念是Day_t = Day_t-1在'17:00'开始。目前,该解决方案将Day_t = 在'17:00'开始的Day_t。
2个回答

2

您在这里实际上不需要使用 np.where,因为您只是对一个参数进行过滤。而且,else 部分被设置为 0。因此,在此步骤之后获取的索引绝对没有减少。

相反,您应该执行以下操作:

1.建立一个布尔掩码,以筛选 hour 属性大于或等于 17 的日期时间,并添加一天的偏移量:

arr = ts.index
idx = arr[arr.hour >= 17] + pd.offsets.Day(1)

2.根据修改后的索引重新索引:

ts_clip = ts.reindex(idx)

3. 执行 pivot 操作:

pd.pivot_table(ts_clip, index=ts_clip.index.date, columns=ts_clip.index.time, values=0)

enter image description here


Edit

ts_clip = ts.iloc[np.argwhere(ts.index.hour.__eq__(17)).ravel()[0]:]
ts_clip_shift = ts_clip.tshift(-17, freq='H')
df = pd.pivot_table(ts_clip_shift, index=(ts_clip_shift.index + pd.offsets.Day(n=1)), 
                    columns=ts_clip_shift.index.time, values=0)
df.columns= ts_clip.iloc[:len(df.columns)].index.time

检查 DF 特性:

df.info()
<class 'pandas.core.frame.DataFrame'>
Index: 7 entries, 2013-01-02 to 2013-01-08
Columns: 144 entries, 17:00:00 to 16:50:00
dtypes: float64(144)
memory usage: 7.9+ KB

1
您提供的解决方案“切分”了数据,每天的时间段是从“17:00”到“23:50”。我需要每天的时间段从“17:00”到“16:50”。 - hernanavella
1
我发现了问题。在某个时候,该过程将天数错误地向后移动了。想法是Day_t = 从Day_t-1开始于'17:00'。目前,解决方案是将Day_t = 从Day_t开始于'17:00'。我添加了一条注释。 - hernanavella
现在你应该没问题了。想法是-等到第一天的17:00小时到来。只从这个索引开始我们的移位系列。然而唯一的变化是,在执行枢轴时,仅为其索引参数提供1天的偏移量,保持所有列中的其他值不变。这对应于(day-day @ new index)= 1 day(滞后)。因此,我们最初在2013/1/1→2013/1/7的日期现在变为2013/1/2→2013/1/8,如“info”输出所示。 - Nickil Maveli

2

因此我需要画一些图片,所以这里它们:

# Step 1:

df1 = df.ix[:,         :'16:59'] # http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.ix.html
df2 = df.ix[:, '17:00' :       ]

# Step 2:

df3 = df2.shift(periods = 1) # http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.shift.html

# Step 3: 

df4 = pandas.concat([df3, df1], axis = 1) # http://pandas.pydata.org/pandas-docs/stable/generated/pandas.concat.html

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接