我有一个多索引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()
方法更快,扩展性更好。
通过第一级选择值,然后对每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