Well, I had no idea this was a general python question (and not
pandas)... well, what do you know, pandas fits in perfectly here!
If you don't have it, please install it. It's meant for stuff like
this.
pip install pandas
选项1a
您可以逐列构建数据框,并在结果上调用melt
。最后,使用pd.crosstab
计算计数。
import pandas as pd
v = pd.concat([pd.Series(v, name=k) for k, v in d.items()], 1).melt()
pd.crosstab(v.variable, v.value)
value PF101 PF201 PF202 PF204 PF305
variable
G1 2 1 0 1 0
G2 1 0 1 0 0
G3 0 0 1 1 1
G4 1 1 0 0 2
这里,
d
是你的输入字典。
选项1b
或者,使用
pd.DataFrame.from_dict
来加载你的数据;其余代码相同,只需在指定列名的点上稍微更改
melt
和
crosstab
的语法。
v = pd.DataFrame.from_dict(d, orient='index').reset_index().melt('index')
pd.crosstab(v['index'], v.value)
value PF101 PF201 PF202 PF204 PF305
index
G1 2 1 0 1 0
G2 1 0 1 0 0
G3 0 0 1 1 1
G4 1 1 0 0 2
选项2
使用
stack
+
str.get_dummies
的另一种选项:
pd.DataFrame.from_dict(d, orient='index')\
.stack()\
.str.get_dummies()\
.sum(level=0)\
.sort_index()
PF101 PF201 PF202 PF204 PF305
G1 2 1 0 1 0
G2 1 0 1 0 0
G3 0 0 1 1 1
G4 1 1 0 0 2
使用pd.get_dummies
也可以得到类似的解决方案,尽管我敢打赌str.get_dummies
会稍微快一些。
v = pd.DataFrame.from_dict(d, orient='index')\
.stack()\
.reset_index(level=1, drop=True)
pd.get_dummies(v).sum(level=0)
PF101 PF201 PF202 PF204 PF305
G2 1 0 1 0 0
G3 0 0 1 1 1
G1 2 1 0 1 0
G4 1 1 0 0 2
选项三:使用
get_dummies
+
dot
。这是我从 piRSquared 学到的技巧。
v = pd.DataFrame.from_dict(d, orient='index').stack()
pd.get_dummies(v.index.get_level_values(0)).T.dot(pd.get_dummies(v.values))
PF101 PF201 PF202 PF204 PF305
G1 2 1 0 1 0
G2 1 0 1 0 0
G3 0 0 1 1 1
G4 1 1 0 0 2
详情
它的作用是从索引和值中创建 OHEs。
pd.get_dummies(v.index.get_level_values(0))
G1 G2 G3 G4
0 0 1 0 0
1 0 1 0 0
2 0 0 1 0
3 0 0 1 0
4 0 0 1 0
5 1 0 0 0
6 1 0 0 0
7 1 0 0 0
8 1 0 0 0
9 0 0 0 1
10 0 0 0 1
11 0 0 0 1
12 0 0 0 1
并且,
pd.get_dummies(v.values)
PF101 PF201 PF202 PF204 PF305
0 1 0 0 0 0
1 0 0 1 0 0
2 0 0 1 0 0
3 0 0 0 1 0
4 0 0 0 0 1
5 1 0 0 0 0
6 0 1 0 0 0
7 0 0 0 1 0
8 1 0 0 0 0
9 1 0 0 0 0
10 0 0 0 0 1
11 0 0 0 0 1
12 0 1 0 0 0
最后,找到这两个张量的点积,结果是交叉制表。