另一种考虑的方法可能是简单地使用.loc 来导航由pandas.crosstab 生成的分层索引,尽管会失去一点可读性。以下示例说明了这一点:
import pandas as pd
import numpy as np
np.random.seed(1234)
df = pd.DataFrame(
{
"a": np.random.choice([1, 2], 5, replace=True),
"b": np.random.choice([11, 12, 13], 5, replace=True),
"c": np.random.choice([21, 22, 23], 5, replace=True),
}
)
df
输出
a b c
0 2 11 23
1 2 11 23
2 1 12 23
3 2 12 21
4 1 12 21
crosstab 输出为:
cross_tab = pd.crosstab(
index=df.a, columns=[df.b, df.c], rownames=["a"], colnames=["b", "c"]
)
cross_tab
b 11 12
c 23 21 23
a
1 0 1 1
2 2 1 0
现在假设您想在a==2、b==11 和c==23 时访问值,那么就这样做
cross_tab.loc[2].loc[11].loc[23]
2
为什么会这样? .loc 允许通过索引标签进行选择。在crosstab 输出的数据框中,我们以前的列值现在变成了索引标签。因此,对于我们所做的每个.loc 选择,它都会给出与该索引标签对应的数据帧切片。让我们一步一步导航cross_tab.loc[2].loc[11].loc[23]:
cross_tab.loc[2]
产量:
b c
11 23 2
12 21 1
23 0
Name: 2, dtype: int64
下一个:
cross_tab.loc[2].loc[11]
产量:
c
23 2
Name: 2, dtype: int64
我们终于有了
cross_tab.loc[2].loc[11].loc[23]
产生:
2
为什么我说这会降低可读性?因为要理解这个选择,你必须知道交叉表是如何创建的,即行是a,列的顺序是[b, c]。您必须知道这一点才能解释cross_tab.loc[2].loc[11].loc[23] 会做什么。但我发现这通常是一个很好的权衡。