基于多个 1 级列的子集多索引 DataFrame
Subset multi-indexed DataFrame based on multiple level 1 columns
我有一个 multi=indexed DataFrame,但我只想为每个级别 1 的每个级别 0 变量保留两列(即列 'one' 和 'two')。我可以分别对它们进行子集化,但我想一起做,这样我就可以并排放置这些值
这是 DataFrame
index = pd.MultiIndex.from_tuples(list(zip(*[['bar1', 'foo1', 'bar1', 'foo2','bar3','foo3'], ['one','two','three','two','one','four']])))
df = pd.DataFrame(np.random.randn(2, 6), columns=index)
这是对级别 1 中的一列进行子集化的方法
df.iloc[:, df.columns.get_level_values(1)== 'one']
# or
df.xs('one', level=1, axis=1)
# but adding two columns within either command will not work e.g.
df.xs(('one','two), level=1, axis=1)
这将是预期的输出
bar1 foo1 foo2 bar3
one two two one
0 -0.508272 -0.195379 0.865563 2.002205
1 -0.771565 1.360479 1.900931 -1.589277
这是使用 pd.IndexSlice
的一种方法:
idnx = pd.IndexSlice[:, ['one', 'two']]
df.loc[:, idnx]
输出:
bar1 bar3 foo1 foo2
one one two two
0 0.589999 0.261224 -0.106588 -2.309628
1 0.646201 -0.491110 0.430724 1.027424
使用鲜为人知的参数 axis
的另一种方式 pd.DataFrame.loc
:
df.loc(axis=1)[:, ['one', 'two']]
输出:
bar1 bar3 foo1 foo2
one one two two
0 0.589999 0.261224 -0.106588 -2.309628
1 0.646201 -0.491110 0.430724 1.027424
注意: 此参数未在 pd.DataFrame.loc 的文档 API 中列出,但被引用在用户指南中的 MultiIndex / Advanced indexing 部分的 Using Slicers 段落中关于中间路径的示例。
您可以reindex
并指定level
。
df.reindex(['one', 'two'], axis=1, level=1)
bar1 foo1 foo2 bar3
one two two one
0 0.276056 1.956400 -1.495128 1.582220
1 -0.383178 1.159138 -1.646173 0.821942
我们可以使用Index.isin
on a specific level to create a Boolean index and select with loc
:
df.loc[:, df.columns.isin(['one', 'two'], level=1)]
df
:
bar1 foo1 foo2 bar3
one two two one
0 0.042062 -0.233098 0.620974 0.330957
1 0.524495 -0.394930 0.572631 0.499279
检查旧时尚get_level_values
out = df.loc[:,df.columns.get_level_values(1).isin(['one','two'])]
Out[454]:
bar1 foo1 foo2 bar3
one two two one
0 -0.705540 -1.175132 -0.572076 -1.549703
1 0.277905 1.789925 1.104225 0.104453
我有一个 multi=indexed DataFrame,但我只想为每个级别 1 的每个级别 0 变量保留两列(即列 'one' 和 'two')。我可以分别对它们进行子集化,但我想一起做,这样我就可以并排放置这些值
这是 DataFrame
index = pd.MultiIndex.from_tuples(list(zip(*[['bar1', 'foo1', 'bar1', 'foo2','bar3','foo3'], ['one','two','three','two','one','four']])))
df = pd.DataFrame(np.random.randn(2, 6), columns=index)
这是对级别 1 中的一列进行子集化的方法
df.iloc[:, df.columns.get_level_values(1)== 'one']
# or
df.xs('one', level=1, axis=1)
# but adding two columns within either command will not work e.g.
df.xs(('one','two), level=1, axis=1)
这将是预期的输出
bar1 foo1 foo2 bar3
one two two one
0 -0.508272 -0.195379 0.865563 2.002205
1 -0.771565 1.360479 1.900931 -1.589277
这是使用 pd.IndexSlice
的一种方法:
idnx = pd.IndexSlice[:, ['one', 'two']]
df.loc[:, idnx]
输出:
bar1 bar3 foo1 foo2
one one two two
0 0.589999 0.261224 -0.106588 -2.309628
1 0.646201 -0.491110 0.430724 1.027424
使用鲜为人知的参数 axis
的另一种方式 pd.DataFrame.loc
:
df.loc(axis=1)[:, ['one', 'two']]
输出:
bar1 bar3 foo1 foo2
one one two two
0 0.589999 0.261224 -0.106588 -2.309628
1 0.646201 -0.491110 0.430724 1.027424
注意: 此参数未在 pd.DataFrame.loc 的文档 API 中列出,但被引用在用户指南中的 MultiIndex / Advanced indexing 部分的 Using Slicers 段落中关于中间路径的示例。
您可以reindex
并指定level
。
df.reindex(['one', 'two'], axis=1, level=1)
bar1 foo1 foo2 bar3
one two two one
0 0.276056 1.956400 -1.495128 1.582220
1 -0.383178 1.159138 -1.646173 0.821942
我们可以使用Index.isin
on a specific level to create a Boolean index and select with loc
:
df.loc[:, df.columns.isin(['one', 'two'], level=1)]
df
:
bar1 foo1 foo2 bar3
one two two one
0 0.042062 -0.233098 0.620974 0.330957
1 0.524495 -0.394930 0.572631 0.499279
检查旧时尚get_level_values
out = df.loc[:,df.columns.get_level_values(1).isin(['one','two'])]
Out[454]:
bar1 foo1 foo2 bar3
one two two one
0 -0.705540 -1.175132 -0.572076 -1.549703
1 0.277905 1.789925 1.104225 0.104453