假设您有以下数据:
records = [
{'group': 'A', 'name': 'Chris', 'is_male': True, 'smoker': False},
{'group': 'A', 'name': 'Bob', 'is_male': True, 'smoker': True},
{'group': 'A', 'name': 'Dana', 'is_male': False, 'smoker': False},
{'group': 'B', 'name': 'Alice', 'is_male': False, 'smoker': True},
{'group': 'B', 'name': 'Michael', 'is_male': True, 'smoker': True},
{'group': 'B', 'name': 'Ron', 'is_male': True, 'smoker': True},
{'group': 'C', 'name': 'Rihanna', 'is_male': False, 'smoker': True},
{'group': 'C', 'name': 'Madonna', 'is_male': False, 'smoker': True},
{'group': 'C', 'name': 'Cher', 'is_male': False, 'smoker': False},
{'group': 'C', 'name': 'John', 'is_male': True, 'smoker': True},
]
data = pd.DataFrame.from_dict(records)
如果我们这样做:
data.groupby(['group', 'is_male', 'smoker']).count().reset_index()
我们得到:
group is_male smoker name
A False False 1
A True False 1
A True True 1
B False True 1
B True True 2
C False False 1
C False True 2
C True True 1
我想做的是获得相同的数据,但以百分比表示,乘以group
的大小
例如,在B
组中,我们将得到1/3
和2/3
我该怎么做呢?
你可以试试crosstab
:
s = pd.crosstab(data['group'], [data['is_male'], data['smoker']], normalize='index')
输出:
is_male False True
smoker False True False True
group
A 0.333333 0.000000 0.333333 0.333333
B 0.000000 0.333333 0.000000 0.666667
C 0.250000 0.500000 0.000000 0.250000
要匹配长格式,请使用stack
:
s.stack(level=(0,1)).reset_index(name='name')
输出:
group is_male smoker name
0 A False False 0.333333
1 A False True 0.000000
2 A True False 0.333333
3 A True True 0.333333
4 B False False 0.000000
5 B False True 0.333333
6 B True False 0.000000
7 B True True 0.666667
8 C False False 0.250000
9 C False True 0.500000
10 C True False 0.000000
11 C True True 0.250000