获取Pandas交叉表中的每个元素

问题描述 投票:0回答:4

我有一个数据集如下:

a,b,c
1,1,1
1,1,1
1,1,2
2,1,2
2,1,1
2,2,1

我用 pandas 创建了交叉表:

 cross_tab = pd.crosstab(index=a, columns=[b, c], rownames=['a'], colnames=['b', 'c'])

我的交叉表作为输出给出:

b        1     2
c        1  2  1
a        
1        2  1  0
2        1  1  1

我想针对给定的每个 a、b 和 c 值迭代此交叉表。我如何获得诸如

cross_tab[a=1][b=1, c=1]
之类的值?谢谢。

python pandas crosstab contingency
4个回答
2
投票

您正在寻找

df2.xxx.get_level_values
:

In [777]: cross_tab.loc[cross_tab.index.get_level_values('a') == 1,\
                        (cross_tab.columns.get_level_values('b') == 1)\
                      & (cross_tab.columns.get_level_values('c') == 1)]
Out[777]: 
b  1
c  1
a   
1  2

1
投票

您可以使用切片机

a,b,c = 1,1,1
idx = pd.IndexSlice
print (cross_tab.loc[a, idx[b,c]])
2

您还可以通过

df
DataFrame.unstack
 重塑 
reorder_levels
,然后使用
loc
:

a = cross_tab.unstack().reorder_levels(('a','b','c'))
print (a)
a  b  c
1  1  1    2
2  1  1    1
1  1  2    1
2  1  2    1
1  2  1    0
2  2  1    1
dtype: int64

print (a.loc[1,1,1])
2

1
投票

另一种考虑的方法,尽管会损失一点可读性,可能是简单地使用

.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]
会做什么。 但我发现这通常是一个很好的权衡。


0
投票

使用@AlokLal提供的数据:

在当前版本的 Python (3.11.2) 中,

cross_tab.loc[2].loc[11]
不起作用。错误是:
ValueError: No axis named 11 for object type Series

一次使用

.loc
功能如下:

>>> print(cross_tab)
b 11 12      
c 22 21 22 23
a            
1  0  0  1  0
2  2  1  0  1


>>> print(cross_tab.loc[2])
b   c 
11  22    2
12  21    1
    22    0
    23    1
Name: 2, dtype: int64


>>> print(cross_tab.loc[2,12])
c
21    1
22    0
23    1
Name: 2, dtype: int64


>>> print(cross_tab.loc[2,12].loc[22])
0
© www.soinside.com 2019 - 2024. All rights reserved.