Как расширить логику выбора из DataFrame на основе первых N-1 уровней, когда N> 2?
В качестве примера рассмотрим DataFrame:
midx = pd.MultiIndex.from_product([[0, 1], [10, 20, 30], ["a", "b"]])
df = pd.DataFrame(1, columns=midx, index=np.arange(3))
In[11]: df
Out[11]:
0 1
10 20 30 10 20 30
a b a b a b a b a b a b
0 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1 1 1 1 1 1
Здесь, легко выбрать столбцы, где 0 или 1 находятся на первом уровне:
df[[0, 1]]
Но та же логика не распространяется на выбор столбцов с 0 или 1 в первом и 10 или 20 во второмуровень:
In[13]: df[[(0, 10), (0, 20), (1, 10), (1, 20)]]
ValueError: operands could not be broadcast together with shapes (4,2) (3,) (4,2)
Работает:
df.loc[:, pd.IndexSlice[[0, 1], [10, 20], :]]
, но это громоздко, особенно когда селектор нужно извлечь из другого DataFrame с двухуровневым MultiIndex:
idx = df.columns.droplevel(2)
In[16]: idx
Out[16]:
MultiIndex(levels=[[0, 1], [10, 20, 30]],
labels=[[0, 0, 0, 0, 0, 0, 1, 1, 1, ... 1, 2, 2]])
In[17]: df[idx]
ValueError: operands could not be broadcast together with shapes (12,2) (3,) (12,2)
РЕДАКТИРОВАТЬ: В идеале я также хотел бы иметь возможность упорядочивать столбцы таким образом, а не просто выбирать их - опять же, в духе df[[1, 0]]
возможность упорядочить столбцы на основепервый уровень.