首页 > 解决方案 > pandas方法交叉表的使用

问题描述

我想对两个系列(s1 和 s2)进行交叉制表,并出现以下错误:“无法从重复轴重新索引”

s1=pd.Series(['ot','bx','bx','bx','ot','ot','med','med','bx','med'],index=['a','b','c','a','b','c','a','b','c','a'])

s2=pd.Series(['adulto','adulto','idoso','adulto','jovem','jovem','adulto','jovem','jovem','adulto'],index=['a','b','c','a','b','c','a','b','c','a'])

print(pd.crosstab(s1,s2))

我试图更改索引,但它没有工作。

标签: pythonpandascrosstab

解决方案


这是发生在函数幕后的 DataFrame 构造问题crosstabcrosstab尝试从提供的系列DataFrame中创建一个。pivot_table这会导致索引问题。这可以通过以下方式复制:

df = pd.DataFrame({'a': s1, 'b': s2}, index=s1.index.intersection(s2.index))

实际发生的源代码以供参考。crosstab


假设 out 系列可以 1 对 1 对齐(行顺序),我们可以简单地使用.valuesor删除索引.to_numpy

pd.crosstab(s1.values, s2.values)

col_0  adulto  idoso  jovem
row_0                      
bx          2      1      1
med         2      0      1
ot          1      0      2

或者通过删除非唯一索引reset_index

pd.crosstab(s1.reset_index(drop=True), s2.reset_index(drop=True))

col_0  adulto  idoso  jovem
row_0                      
bx          2      1      1
med         2      0      1
ot          1      0      2

如果 Series 没有方便地在位置上正确对齐,我们可以枚举每个索引值并merge使用groupby cumcount来创建一个统一索引的 DataFrame,然后我们可以采用crosstab

df1 = s1.reset_index(name='s1')
df2 = s2.reset_index(name='s2')

df3 = df1.merge(df2,
                left_on=['index', df1.groupby('index').cumcount()],
                right_on=['index', df2.groupby('index').cumcount()])

df3

  index  key_1   s1      s2
0     a      0   ot  adulto
1     b      0   bx  adulto
2     c      0   bx   idoso
3     a      1   bx  adulto
4     b      1   ot   jovem
5     c      1   ot   jovem
6     a      2  med  adulto
7     b      2  med   jovem
8     c      2   bx   jovem
9     a      3  med  adulto

现在索引相对于它们在索引组中的位置对齐,而不是它们在系列中的绝对位置:

pd.crosstab(df3['s1'], df3['s2'])

s2   adulto  idoso  jovem
s1                       
bx        2      1      1
med       2      0      1
ot        1      0      2

*这里的结果是一样的。


推荐阅读