40_Pandas中crosstab进行交叉制表(计算每个类别的出现次数和频率)

40_Pandas中crosstab进行交叉制表(计算每个类别的出现次数和频率)

可以使用pandas.crosstab()函数完成交叉表分析。 可以为每个类别的分类数据(分类数据,定性数据)计算样本数(出现次数/频率)。

如果要计算每个类别的平均值而不是出现次数,请使用数据透视表pandas.pivot_table()。
这里,

  • pandas.crosstab()函数的基本用法
  • 计算每个类别的小计/总计:参数margins
  • 标准化整个/行/列:参数normalize
    将予以描述。 将以泰坦尼克号的生存信息数据为例。
import pandas as pd

df = pd.read_csv('./data/40/train.csv', index_col=0).drop(['Name', 'Ticket', 'SibSp', 'Parch'], axis=1)

print(df.head())
#              Survived  Pclass     Sex   Age     Fare Cabin Embarked
# PassengerId
# 1                   0       3    male  22.0   7.2500   NaN        S
# 2                   1       1  female  38.0  71.2833   C85        C
# 3                   1       3  female  26.0   7.9250   NaN        S
# 4                   1       1  female  35.0  53.1000  C123        S
# 5                   0       3    male  35.0   8.0500   NaN        S

pandas.crosstab()函数的基本用法

在第一个参数索引中指定pandas.DataFrame列(= pandas.Series)作为结果行标题,在第二个参数列中指定pandas.DataFrame列(= pandas.Series)作为结果列标题。

注意,与pandas.pivot_table()不同,它不是由pandas.DataFrame对象及其列名指定的。

print(pd.crosstab(df['Sex'], df['Pclass']))
# Pclass    1    2    3
# Sex                  
# female   94   76  144
# male    122  108  347

pandas.crosstab()函数返回pandas.DataFrame。

print(type(pd.crosstab(df['Sex'], df['Pclass'])))
# <class 'pandas.core.frame.DataFrame'>

还可以在参数索引和列中指定pandas.Series的列表。结果以多索引(分层索引)pandas.DataFrame的形式返回。

print(pd.crosstab([df['Sex'], df['Survived']], [df['Pclass'], df['Embarked']]))
# Pclass            1         2          3
# Embarked          C  Q   S  C  Q   S   C   Q    S
# Sex    Survived
# female 0          1  0   2  0  0   6   8   9   55
#        1         42  1  46  7  2  61  15  24   33
# male   0         25  1  51  8  1  82  33  36  231
#        1         17  0  28  2  0  15  10   3   34

请参阅以下文章,了解如何选择多索引pandas.DataFrame的行和列。

计算每个类别的小计/总计:参数margins

如果参数margin为True,则可以计算每个类别的小计和总计。

print(pd.crosstab([df['Sex'], df['Survived']], [df['Pclass'], df['Embarked']],
                  margins=True))
# Pclass            1           2           3           All
# Embarked          C  Q    S   C  Q    S   C   Q    S     
# Sex    Survived                                          
# female 0          1  0    2   0  0    6   8   9   55   81
#        1         42  1   46   7  2   61  15  24   33  231
# male   0         25  1   51   8  1   82  33  36  231  468
#        1         17  0   28   2  0   15  10   3   34  109
# All              85  2  127  17  3  164  66  72  353  889

可以通过参数margins_name指定小计/总行标签/列标签。默认为“all”。

print(pd.crosstab([df['Sex'], df['Survived']], [df['Pclass'], df['Embarked']],
                  margins=True, margins_name='Total'))
# Pclass            1           2           3          Total
# Embarked          C  Q    S   C  Q    S   C   Q    S      
# Sex    Survived                                           
# female 0          1  0    2   0  0    6   8   9   55    81
#        1         42  1   46   7  2   61  15  24   33   231
# male   0         25  1   51   8  1   82  33  36  231   468
#        1         17  0   28   2  0   15  10   3   34   109
# Total            85  2  127  17  3  164  66  72  353   889

标准化整个/行/列:参数normalize

指定参数normalize时,可以对整个,行和列的结果进行1归一化(归一化)。 如果normalize = True或normalize =‘all’,则将其标准化以使总数为1。

print(pd.crosstab(df['Sex'], df['Pclass'], margins=True, normalize=True))
# Pclass         1         2         3       All
# Sex                                           
# female  0.105499  0.085297  0.161616  0.352413
# male    0.136925  0.121212  0.389450  0.647587
# All     0.242424  0.206510  0.551066  1.000000

如果normalize =‘index’,则将其标准化,以使每行的总数为1。

print(pd.crosstab(df['Sex'], df['Pclass'], margins=True, normalize='index'))
# Pclass         1         2         3
# Sex                                 
# female  0.299363  0.242038  0.458599
# male    0.211438  0.187175  0.601386
# All     0.242424  0.206510  0.551066

如果normalize =‘columns’,则将其标准化,以使每列的总数为1。

print(pd.crosstab(df['Sex'], df['Pclass'], margins=True, normalize='columns'))
# Pclass         1         2         3       All
# Sex                                           
# female  0.435185  0.413043  0.293279  0.352413
# male    0.564815  0.586957  0.706721  0.647587

请注意,如果在列表中为参数margins = True和参数索引和列指定了多列,则如果在指定方向上对多索引进行标准化,则会发生错误。

# print(pd.crosstab(df['Sex'], [df['Pclass'], df['Embarked']],
#                   margins=True, normalize=True))
# TypeError: Expected tuple, got str

print(pd.crosstab(df['Sex'], [df['Pclass'], df['Embarked']],
                  margins=True, normalize='index'))
# Pclass           1                             2                      \
# Embarked         C         Q         S         C         Q         S   
# Sex                                                                    
# female    0.137821  0.003205  0.153846  0.022436  0.006410  0.214744   
# male      0.072790  0.001733  0.136915  0.017331  0.001733  0.168111   
# All       0.095613  0.002250  0.142857  0.019123  0.003375  0.184477   
# Pclass           3                      
# Embarked         C         Q         S  
# Sex                                     
# female    0.073718  0.105769  0.282051  
# male      0.074523  0.067591  0.459272  
# All       0.074241  0.080990  0.397075  

# print(pd.crosstab(df['Sex'], [df['Pclass'], df['Embarked']],
#                   margins=True, normalize='columns'))
# ValueError: Length of new names must be 1, got 2

如果margins = False(默认值),则没有问题。

print(pd.crosstab(df['Sex'], [df['Pclass'], df['Embarked']], normalize=True))
# Pclass           1                             2                      \
# Embarked         C         Q         S         C         Q         S   
# Sex                                                                    
# female    0.048369  0.001125  0.053993  0.007874  0.002250  0.075366   
# male      0.047244  0.001125  0.088864  0.011249  0.001125  0.109111   
# Pclass           3                     
# Embarked         C        Q         S  
# Sex                                    
# female    0.025872  0.03712  0.098988  
# male      0.048369  0.04387  0.298088  

print(pd.crosstab(df['Sex'], [df['Pclass'], df['Embarked']], normalize='index'))
# Pclass           1                             2                      \
# Embarked         C         Q         S         C         Q         S   
# Sex                                                                    
# female    0.137821  0.003205  0.153846  0.022436  0.006410  0.214744   
# male      0.072790  0.001733  0.136915  0.017331  0.001733  0.168111   
# Pclass           3                      
# Embarked         C         Q         S  
# Sex                                     
# female    0.073718  0.105769  0.282051  
# male      0.074523  0.067591  0.459272  

print(pd.crosstab(df['Sex'], [df['Pclass'], df['Embarked']], normalize='columns'))
# Pclass           1                        2                             3  \
# Embarked         C    Q         S         C         Q         S         C   
# Sex                                                                         
# female    0.505882  0.5  0.377953  0.411765  0.666667  0.408537  0.348485   
# male      0.494118  0.5  0.622047  0.588235  0.333333  0.591463  0.651515   
# Pclass                        
# Embarked         Q         S  
# Sex                           
# female    0.458333  0.249292  
# male      0.541667  0.750708  
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值