Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何获取数据帧中一行的百分比?_Python_Pandas_Numpy_Scipy_Percentile - Fatal编程技术网

Python 如何获取数据帧中一行的百分比?

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']

我需要为数据帧(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'].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')