Pandas: .groupby().size() 和百分比
我有一个数据表(DataFrame),它是通过执行 df.groupby().size()
操作得到的,长得像这样:
Localization RNA level
cytoplasm 1 Non-expressed 7
2 Very low 13
3 Low 8
4 Medium 6
5 Moderate 8
6 High 2
7 Very high 6
cytoplasm & nucleus 1 Non-expressed 5
2 Very low 8
3 Low 2
4 Medium 10
5 Moderate 16
6 High 6
7 Very high 5
cytoplasm & nucleus & plasma membrane 1 Non-expressed 6
2 Very low 3
3 Low 3
4 Medium 7
5 Moderate 8
6 High 4
7 Very high 1
我想做的是计算每个类别(也就是最后一列来自 .size()
的数据)占该类别总数的百分比。
举个例子:在 cytoplasm
这个类别中,总共有 50 次出现(7 + 13 + 8 + 6 + 8 + 2 + 6),所以 Non-expressed
和 Very low
的 RNA 水平分别占 14% 和 26%。
有没有简单的方法可以做到这一点?我现在的方法感觉有点绕,就是为每个 Localization
创建一个新的数据表,然后再从那里开始处理,但这样会有很多行,最后还得把所有生成的数据表合并在一起。我希望能有更聪明的办法来解决这个问题!
1 个回答
19
这里有一个完整的例子,基于pandas库中的groupby
和sum
函数。基本的想法是根据'Localization'
来对数据进行分组,然后对每个组应用一个函数。
import pandas as pd
from io import StringIO
#For Python 2, replace previous line with: from StringIO import StringIO
data = \
"""Localization,RNA level,Size
cytoplasm ,1 Non-expressed, 7
cytoplasm ,2 Very low ,13
cytoplasm ,3 Low , 8
cytoplasm ,4 Medium , 6
cytoplasm ,5 Moderate , 8
cytoplasm ,6 High , 2
cytoplasm ,7 Very high , 6
cytoplasm & nucleus ,1 Non-expressed, 5
cytoplasm & nucleus ,2 Very low , 8
cytoplasm & nucleus ,3 Low , 2
cytoplasm & nucleus ,4 Medium ,10
cytoplasm & nucleus ,5 Moderate ,16
cytoplasm & nucleus ,6 High , 6
cytoplasm & nucleus ,7 Very high , 5
cytoplasm & nucleus & plasma membrane,1 Non-expressed, 6
cytoplasm & nucleus & plasma membrane,2 Very low , 3
cytoplasm & nucleus & plasma membrane,3 Low , 3
cytoplasm & nucleus & plasma membrane,4 Medium , 7
cytoplasm & nucleus & plasma membrane,5 Moderate , 8
cytoplasm & nucleus & plasma membrane,6 High , 4
cytoplasm & nucleus & plasma membrane,7 Very high , 1"""
# Create the dataframe
df = pd.read_csv(StringIO(data))
df['Localization'].str.strip()
df['RNA level'].str.strip()
df['Size'].astype(int)
df['Percent'] = df.groupby('Localization')['Size'].transform(lambda x: x/sum(x))