python - 具有无序分类变量的 Pandas 交叉表
问题描述
对于一个有趣的项目,我生成了一个包含所有当前存在的口袋妖怪(916 个,不包括 Megas 或其他形式)的数据集,并收集了有关基本统计数据、能力和类型的数据。现在我想生成一个交叉表,显示每种类型组合的分布。当前对数据进行编码,使得第一类和第二类是单独的变量,Type1
并且Type2
. 这种格式适用于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 函数,那么也许我可以通过矩阵运算来实现。如果做不到这一点,我认为可能会有一个缓慢的迭代过程来实现这一点。
解决方案
一种选择是用于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 中如何出现,所有类型都以相同的顺序出现,并且无论它们在列中出现的顺序如何,值计数都会产生正确的值。
推荐阅读
- javascript - 从本地文件夹而不是 .js 中的网站加载图像
- algorithm - 如何在不使用蛮力的情况下找到给定不完整数字的最小倍数
- c# - ASP.NET Core Web API 将所有枚举作为第 0 个选项发布
- powershell - 如何使用 VSCode 中详述的 -OutPut 快速运行 Pester?
- javascript - D3js 数据格式
- javascript - 如果您没有在 iOS Safari 上点击按钮,则单击事件不会触发
- javascript - 如何在Materialize CSS中动态匹配选择输入到选择的选项?
- javascript - 我创建了一个实用程序函数,但无法让 useNavigare 在那里工作如何解决这个问题
- elementor - 使用 Elementor Pro 进行反跳电子邮件验证
- go - 为什么 http.SetCookie() 不添加 cookie?