如何在multiindex DataFrame的最外层使用iloc分片?

问题描述 投票:0回答:1

我有一个多索引DataFrame,以pd.timestamp作为顶层索引,一些任意参数作为第二层。你可以使用这个代码段来重现一些模拟数据。

level0 = pd.period_range(start='2020-01-01-00:00:00', end='2020-01-01-00:01:00', freq='s')
level1 = ['foo', 'bar', 'foobar']
values = np.random.rand(len(level1)*len(level0))
idx = pd.MultiIndex.from_product([level0, level1], names=['time', 'level1'])
col = ['value']
df = pd.DataFrame(values, idx, col)
print(df)

这将创建输出。

                               value
time                level1          
2020-01-01 00:00:00 foo     0.345507
                    bar     0.147654
                    foobar  0.617000
2020-01-01 00:00:01 foo     0.430975
                    bar     0.783075
...                              ...
2020-01-01 00:00:59 bar     0.027083
                    foobar  0.553220
2020-01-01 00:01:00 foo     0.253957
                    bar     0.569881
                    foobar  0.976768

现在我想把每一个 n-第2次作为我进一步计算的数据。我的第一个方法是使用 .iloc[::n]如果数据框架先不堆栈,则工作正常。因此,这段代码 df.unstack().iloc[::5].stack() 产生的正是我想要的输出。

                               value
time                level1          
2020-01-01 00:00:00 bar     0.147654
                    foo     0.345507
                    foobar  0.617000
2020-01-01 00:00:05 bar     0.083129
                    foo     0.591585
                    foobar  0.660372
2020-01-01 00:00:10 bar     0.460798
                    foo     0.308138
                    foobar  0.622412
...                              ...
2020-01-01 00:00:55 bar     0.700964
                    foo     0.556782
                    foobar  0.601582
2020-01-01 00:01:00 bar     0.569881
                    foo     0.253957
                    foobar  0.976768

然而,当df变大时,解堆栈和堆叠会耗费大量的资源。我觉得有一个简单、优雅和 "廉价 "的解决方案,但我却无法掌握。

有没有一种解决方案,可以选择每一个 n-th时间戳,避免了数据的解叠?

EDIT:对于读到这里的人来说。虽然jezraels的答案是一个很好的方法,也给了我一些处理问题的方法,但是对于我的情况(一个月的secondly数据和大约300个 "level1 "的条目)来说,事实证明 unstack().iloc[::n].stack() 方法更快,扩展性更好。

python pandas slice
1个回答
3
投票

通过第一级选择值,然后对每5个值进行分片,最后传给 DataFrame.loc:

df1 = df.loc[df.index.levels[0][::5]]
print(df1)

                               value
time                level1          
2020-01-01 00:00:00 foo     0.350853
                    bar     0.998113
                    foobar  0.077340
2020-01-01 00:00:05 foo     0.029292
                    bar     0.394105
                    foobar  0.375882
2020-01-01 00:00:10 foo     0.878306
                    bar     0.152500
                    foobar  0.299017
2020-01-01 00:00:15 foo     0.821039
                    bar     0.298991
                    foobar  0.496110
2020-01-01 00:00:20 foo     0.523729
                    bar     0.928747
                    foobar  0.902535
2020-01-01 00:00:25 foo     0.128496
                    bar     0.126517
                    foobar  0.802517
2020-01-01 00:00:30 foo     0.539462
                    bar     0.754518
                    foobar  0.243328
2020-01-01 00:00:35 foo     0.159771
                    bar     0.058187
                    foobar  0.508651
2020-01-01 00:00:40 foo     0.847019
                    bar     0.688022
                    foobar  0.368563
2020-01-01 00:00:45 foo     0.575865
                    bar     0.531090
                    foobar  0.756400
2020-01-01 00:00:50 foo     0.584265
                    bar     0.155704
                    foobar  0.734554
2020-01-01 00:00:55 foo     0.035894
                    bar     0.047678
                    foobar  0.746624
2020-01-01 00:01:00 foo     0.254821
                    bar     0.756032
                    foobar  0.694809
© www.soinside.com 2019 - 2024. All rights reserved.