【问题标题】:Pandas Crosstab table with Unordered Categorical Variables具有无序分类变量的 Pandas 交叉表
【发布时间】:2021-09-21 03:09:37
【问题描述】:

为了一个有趣的项目,我生成了一个包含所有当前存在的口袋妖怪(916 个,不包括 Megas 或其他形式)的数据集,并收集了有关基本统计数据、能力和类型的数据。现在我想生成一个交叉表,显示每种类型组合的分布。当前对数据进行编码,使得第一和第二类型是单独的变量Type1Type2。这种格式适用于pd.crosstab(),假设类型的顺序不同,('Flying','Normal')('Normal','Flying') 不一样;但是,游戏没有做出这样的区分。我想生成反映这一点的频率表——基本上将pd.crosstab() 表沿对角线折叠成两半。

#### For data structured like...
In[1]: dfNatDex[dfNatDex['DexNum']<10]
Out[4]: 
    DexNum        Name  Type1   Type2
0      1.0   Bulbasaur  grass  poison
1      2.0     Ivysaur  grass  poison
2      3.0    Venusaur  grass  poison
3      4.0  Charmander   fire    fire
4      5.0  Charmeleon   fire    fire
5      6.0   Charizard   fire  flying
6      7.0    Squirtle  water   water
7      8.0   Wartortle  water   water
8      9.0   Blastoise  water   water

[10 rows x 16 columns]

#### I am getting...
In[2]: crosstab(dfNatDex['Type2'][...],dfNatDex['Type1'][...])
Out[2]: 
Type1   flying  normal  water
Type2                        
flying       3      26      7
normal       0      69      0
water        1       1     67

#### I want to get...
Type1   flying  normal  water
Type2                        
flying       3      26      8
normal       .      69      1
water        .       .     67

我的猜测是,如果我还没有找到用于此的 Pandas 函数,那么也许我可以通过矩阵运算来实现这一点。如果做不到这一点,我认为可能需要一个缓慢的迭代过程来实现这一点。

【问题讨论】:

    标签: python python-3.x pandas categorical-data crosstab


    【解决方案1】:

    一种选择是使用np.sort 对axis=1 上的值进行排序,然后使用value_counts 获取计数:

    import numpy as np
    import pandas as pd
    
    cols = ['Type1', 'Type2']
    types_df = pd.DataFrame(
        np.sort(df[cols], axis=1),
        columns=cols
    ).value_counts().reset_index(name='Count')
    

    types_df:

       Type1   Type2  Count
    0  grass  poison      3
    1  water   water      3
    2   fire    fire      2
    3   fire  flying      1
    

    crosstab 也可以用于已排序的值,但会有很多 0 值可能会掩盖试图展示的信息:

    cols = ['Type1', 'Type2']
    types_df = pd.DataFrame(np.sort(df[cols], axis=1), columns=cols)
    ct_df = pd.crosstab(types_df['Type2'], types_df['Type1'])
    

    ct_df:

    Type1   fire  grass  water
    Type2                     
    fire       2      0      0
    flying     1      0      0
    poison     0      3      0
    water      0      0      3
    

    假设这些类型:

    df[['Type1', 'Type2']]
    
        Type1   Type2
    0  poison   grass  # poison grass
    1   grass  poison  # grass poison
    2   grass  poison
    3    fire    fire
    4    fire    fire
    5    fire  flying
    6   water   water
    7   water   water
    8   water   water
    

    排序后:

    np.sort(df[['Type1', 'Type2']], axis=1)
    
    [['grass' 'poison']  # grass poison
     ['grass' 'poison']  # grass poison
     ['grass' 'poison']
     ['fire' 'fire']
     ['fire' 'fire']
     ['fire' 'flying']
     ['water' 'water']
     ['water' 'water']
     ['water' 'water']]
    

    这样,所有类型都以相同的顺序出现,无论它们在 DataFrame 中的出现方式如何,并且值计数将产生正确的值,无论它们在列中出现的顺序如何。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-05
      • 1970-01-01
      • 2020-11-30
      • 2012-10-10
      • 2022-06-16
      • 2021-09-17
      • 1970-01-01
      • 2016-01-25
      相关资源
      最近更新 更多