我通常处理具有多个级别索引的大型数据帧,我希望根据级别的子集对其进行切片。我不认为有一个简单的方法可以做到这一点。特别是,pandas.IndexSlice
没有提供所需的结果,我将在下面解释。你知道吗
假设我们有这样一个数据帧:
col0 col1
level0 level1 level2
0 0 0 0 0
1 1 1
1 0 2 2
1 3 3
1 0 0 4 4
1 5 5
1 0 6 6
1 7 7
我希望我能像这样切开它:
# This doesn't work!
df.loc[[
(0, 1),
(1, 0),
]]
# ValueError: operands could not be broadcast together with shapes (2,2) (3,) (2,2)
预期结果如下:
col0 col1
level0 level1 level2
0 1 0 2 2
1 3 3
1 0 0 4 4
1 5 5
IndexSlice
做了一些不同的事情,而不是这里想要的:
df.loc[pandas.IndexSlice[[0, 1], [1, 0], :]]
它给出了所需级别的所有组合,而不仅仅是所需级别。你知道吗
我将发表我自己的答案与一些解决办法,我已经想出,但没有一个是完美的,所以请张贴任何其他想法。你知道吗
以下是生成数据的代码:
import pandas
import numpy as np
# Size of the problem
n_levels = 3
n_values_per_level = 2
# Build an example MultiIndex
midx = pandas.MultiIndex.from_product(
[range(n_values_per_level)] * n_levels,
names=['level{}'.format(level) for level in range(n_levels)]
)
# Generate data of the appropriate number of rows
df = pandas.DataFrame(
np.transpose([np.arange(len(midx))] * 2),
columns=['col0', 'col1'],
index=midx)
以下是我发现的一些变通方法,没有一个是完美的:
拆垛
这很管用。缺点是它创建了一个中间数据结构,这个结构可能非常大。在最坏的情况下(当level3不包含重复值时),中间结构是原始结构大小的平方。你知道吗
重置索引
这个解决方案是由@anky\u 91提出的。将索引重置为数据列,然后在切片后再次追加到索引。你知道吗
这是相当有效的。我能想到的唯一缺点是,如果列上有一个多索引(需要检查这个),它可能会弄乱列上的多索引。你知道吗
单独索引和concat
这很管用。但是对于大型数据帧来说,它可能非常慢,因为每个元素都必须单独索引。出于某种原因,它还会删除级别名称。你知道吗
如果
len(slicing_midx) << len(df)
,这可能是最快的合并/比较多索引
这将索引与熊猫.合并、遮罩和切片。我相信这是最有效的,但也很麻烦。你知道吗
相关问题 更多 >
编程相关推荐