Python 如何获取数据帧中一行的百分比?
我需要为数据帧(255M行)中的每一行获取一列的百分比,但找不到任何函数/方法返回它们在Python 如何获取数据帧中一行的百分比?,python,pandas,numpy,scipy,percentile,Python,Pandas,Numpy,Scipy,Percentile,我需要为数据帧(255M行)中的每一行获取一列的百分比,但找不到任何函数/方法返回它们在pd.quantile&np.percentile中使用的方法 我尝试了以下方法/功能- Example DataFrame Values - 0 78 1 38 2 42 3 48 4 31 5 89 6 94 7 102 8 122 9 122 stats.percentileofscore(temp['INCOME']
pd.quantile
&np.percentile
中使用的方法
我尝试了以下方法/功能-
Example DataFrame Values -
0 78
1 38
2 42
3 48
4 31
5 89
6 94
7 102
8 122
9 122
stats.percentileofscore(temp['INCOME'].values, 38, kind='mean')
15.0
stats.percentileofscore(temp['INCOME'].values, 38, kind='strict')
10.0
stats.percentileofscore(temp['INCOME'].values, 38, kind='weak')
20.0
stats.percentileofscore(temp['INCOME'].values, 38, kind='rank')
20.0
temp['INCOME'].rank(pct=True)
1 0.20 (Only showing the 38 value index)
temp['INCOME'].quantile(0.11)
37.93
temp['INCOME'].quantile(0.12)
38.31999999999999
Based on the results above, you can see none of the methods are consistent
with the pd.quantiles() method.
此方法仅返回按顺序排列的值,而不使用我正在查找的百分位数方法。与pd.分位数不一致
.rank(pct=True)
这种方法几乎接近于我所寻找的,但由于某些原因,仍然与“线性插值”方法不完全一致
我已经浏览了与这个问题相关的所有SO答案,但没有一个使用我需要使用的相同插值方法,因此请不要将其标记为重复,除非您可以验证它们使用的是相同的方法
在这一点上,我的最后一个选择是找到所有100%的bin截止值,并以这种方式应用它,或者自己计算线性插值,但这似乎非常低效,将永远无法应用于255M记录
还有其他建议吗
谢谢 这似乎有效:
scipy.stats.percentileofscore
例如:
A = np.sort(temp['INCOME'].values)
np.interp(sample, A, np.linspace(0, 1, len(A)))
请注意,只有当您想要查询足够多的值时,此策略才有意义。否则排序太贵。TL;博士
使用
答复
这其实很简单,一旦你理解了力学。当您查找分数的百分位数时,您已经在每一行中有了分数。剩下的唯一一步是了解您需要小于或等于所选值的百分位数。这正是scipy.stats.percentileofscore()的参数种类='weak'和DataFrame.rank()的方法='average'所做的。要反转它,请使用interpolation='lower'运行Series.quantile()
因此,scipy.stats.percentileofscore()
、Series.rank()
和Series.quantile()
的行为是一致的,如下所示:
sz = temp['INCOME'].size-1
temp['PCNT_LIN'] = temp['INCOME'].rank(method='max').apply(lambda x: 100.0*(x-1)/sz)
INCOME PCNT_LIN
0 78 44.444444
1 38 11.111111
2 42 22.222222
3 48 33.333333
4 31 0.000000
5 89 55.555556
6 94 66.666667
7 102 77.777778
8 122 100.000000
9 122 100.000000
现在在一列PCNT\u RANK
中,您可以得到小于或等于一列INCOME
中的值的比率。但是,如果您想要“插值”比率,它位于列PCNT\u LIN
中。当您使用Series.rank()
进行计算时,它的速度非常快,可以在几秒钟内处理255M个数字
在这里,我将解释如何使用分位数()
和线性插值来获得值:
In[]:
temp = pd.DataFrame([ 78, 38, 42, 48, 31, 89, 94, 102, 122, 122], columns=['INCOME'])
temp['PCNT_RANK']=temp['INCOME'].rank(method='max', pct=True)
temp['POF'] = temp['INCOME'].apply(lambda x: scipy.stats.percentileofscore(temp['INCOME'], x, kind='weak'))
temp['QUANTILE_VALUE'] = temp['PCNT_RANK'].apply(lambda x: temp['INCOME'].quantile(x, 'lower'))
temp['RANK']=temp['INCOME'].rank(method='max')
sz = temp['RANK'].size - 1
temp['PCNT_LIN'] = temp['RANK'].apply(lambda x: (x-1)/sz)
temp['CHK'] = temp['PCNT_LIN'].apply(lambda x: temp['INCOME'].quantile(x))
temp
Out[]:
INCOME PCNT_RANK POF QUANTILE_VALUE RANK PCNT_LIN CHK
0 78 0.5 50.0 78 5.0 0.444444 78.0
1 38 0.2 20.0 38 2.0 0.111111 38.0
2 42 0.3 30.0 42 3.0 0.222222 42.0
3 48 0.4 40.0 48 4.0 0.333333 48.0
4 31 0.1 10.0 31 1.0 0.000000 31.0
5 89 0.6 60.0 89 6.0 0.555556 89.0
6 94 0.7 70.0 94 7.0 0.666667 94.0
7 102 0.8 80.0 102 8.0 0.777778 102.0
8 122 1.0 100.0 122 10.0 1.000000 122.0
9 122 1.0 100.0 122 10.0 1.000000 122.0
我们的数据temp['INCOME']
只有十个值。根据你的公式,第11百分位的排名是
temp['INCOME'].quantile(0.11)
37.93
秩的截断部分为1,对应于值31,秩为2(即下一个bin)的值为38。分数的值是秩的分数部分。这导致了以下结果:
rank = 11*(10-1)/100 + 1 = 1.99
对于值本身,分数
部分必须为零,因此很容易进行反向计算以获得百分位:
31 + (38-31)*(0.99) = 37.93
我希望我说得更清楚。 让我们考虑下面的数据框:
为了获得pandas Dataframe中列的百分比,我们使用以下代码:
p = (rank - 1)*100/(10 - 1)
输出:
美国0.333
中国0.25万
印度0.250000
班加迪什0.166667
姓名:国籍,数据类型:64
为了获得数据框中某列相对于另一个分类列的百分比
survey['Nationality'].value_counts(normalize='index')
输出如下所示
垃圾箱的关闭将非常简单,除非我遗漏了什么:pd.qcut(df.col_name,q=100)
@ALollz是的,这会起作用。但是,我需要根据3个不同列的值将所有255M记录与特定bin匹配。我希望有一个更有效的方法,但这可能是我需要做的。不过,我不确定匹配到这些垃圾箱的最佳方法。我也不完全确定我是否理解,但也许可以先使用stack
只获取一列所有需要查找百分位数的值?然后,您应该能够根据pd.qcut
的输出进行分组,或者首先基于该输出进行分组,并对每个百分位数进行一些计算,而无需显式创建它们。毫不奇怪,您会在10行中得到不同的答案,但我认为所有答案都会(至少几乎)在2.55亿行中收敛,不是吗?我不知道这种具体情况,但在不同的程序(sas/stata/r/etc)之间,对于qcut
,通常会得到稍微不同的答案,因为行数较少,而且质量点也较少。例如,如果25%的值是零或一,那么不同的程序可以采取不同的策略在组之间拆分零或一(因为它们不可避免地跨越2个或更多组)。您能否更明确地说明您对所有输入值的期望百分比值?感谢您提供此解决方案和深入解释!这很有效,而且速度也很快。
survey['Nationality'].value_counts(normalize='index')
pd.crosstab(survey.Sex,survey.Handedness,normalize = 'index')