我想创建一个将(排序的)列表作为其参数并输出包含每个元素的相应百分位数的列表的函数。
例如,fn([1,2,3,4,17])
return [0.0, 0.25, 0.50, 0.75, 1.00]
。
任何人都可以请:
我当前的代码:
def median(mylist):
length = len(mylist)
if not length % 2:
return (mylist[length / 2] + mylist[length / 2 - 1]) / 2.0
return mylist[length / 2]
###############################################################################
# PERCENTILE FUNCTION
###############################################################################
def percentile(x):
"""
Find the correspoding percentile of each value relative to a list of values.
where x is the list of values
Input list should already be sorted!
"""
# sort the input list
# list_sorted = x.sort()
# count the number of elements in the list
list_elementCount = len(x)
#obtain set of values from list
listFromSetFromList = list(set(x))
# count the number of unique elements in the list
list_uniqueElementCount = len(set(x))
# define extreme quantiles
percentileZero = min(x)
percentileHundred = max(x)
# define median quantile
mdn = median(x)
# create empty list to hold percentiles
x_percentile = [0.00] * list_elementCount
# initialize unique count
uCount = 0
for i in range(list_elementCount):
if x[i] == percentileZero:
x_percentile[i] = 0.00
elif x[i] == percentileHundred:
x_percentile[i] = 1.00
elif x[i] == mdn:
x_percentile[i] = 0.50
else:
subList_elementCount = 0
for j in range(i):
if x[j] < x[i]:
subList_elementCount = subList_elementCount + 1
x_percentile[i] = float(subList_elementCount / list_elementCount)
#x_percentile[i] = float(len(x[x > listFromSetFromList[uCount]]) / list_elementCount)
if i == 0:
continue
else:
if x[i] == x[i-1]:
continue
else:
uCount = uCount + 1
return x_percentile
当前,如果我提交percentile([1,2,3,4,17])
,[0.0, 0.0, 0.5, 0.0, 1.0]
则返回列表。
我认为您的示例输入/输出与典型的百分位数计算方法不符。如果将百分位数计算为“数据点的比例严格小于此值”,则最高值应为0.8(因为5个值中的4个小于最大值)。如果您将其计算为“小于或等于此值的数据点百分比”,则最低值应为0.2(因为5个值中的1个等于最小值)。因此,百分位数将为[0, 0.2, 0.4, 0.6, 0.8]
或[0.2, 0.4, 0.6, 0.8, 1]
。您的定义似乎是“数据点的数量严格小于该值,被视为不等于该值的数据点的数量的比例”,但是根据我的经验,这不是一个常见的定义(例如参见Wikipedia)
。
使用典型的百分位数定义,数据点的百分位数等于其等级除以数据点的数量。(例如,请参阅Stats
SE上的此问题,询问如何在R中执行相同的操作。)如何计算百分位数与在计算排名(例如,对绑定值进行排名)上存在差异。该scipy.stats.percentileofscore
函数提供了四种计算百分位数的方法:
>>> x = [1, 1, 2, 2, 17]
>>> [stats.percentileofscore(x, a, 'rank') for a in x]
[30.0, 30.0, 70.0, 70.0, 100.0]
>>> [stats.percentileofscore(x, a, 'weak') for a in x]
[40.0, 40.0, 80.0, 80.0, 100.0]
>>> [stats.percentileofscore(x, a, 'strict') for a in x]
[0.0, 0.0, 40.0, 40.0, 80.0]
>>> [stats.percentileofscore(x, a, 'mean') for a in x]
[20.0, 20.0, 60.0, 60.0, 90.0]
(我使用包含关系的数据集来说明在这种情况下会发生什么。)
“等级”方法为联系组分配的等级等于他们将覆盖的等级的平均值(即,第二名的三路并列获得3的等级,因为它“占据”了等级2、3和4)。“弱”方法根据小于或等于给定点的数据点的比例分配百分位数;“严格”是相同的,但计数点的比例严格小于给定点。“均值”方法是后两者的平均值。
正如Kevin H.
Lin指出的那样,percentileofscore
循环调用效率很低,因为它必须在每次通过时重新计算排名。但是,可以使用提供的不同排名方法轻松地复制这些百分比计算scipy.stats.rankdata
,让您一次计算所有百分比:
>>> from scipy import stats
>>> stats.rankdata(x, "average")/len(x)
array([ 0.3, 0.3, 0.7, 0.7, 1. ])
>>> stats.rankdata(x, 'max')/len(x)
array([ 0.4, 0.4, 0.8, 0.8, 1. ])
>>> (stats.rankdata(x, 'min')-1)/len(x)
array([ 0. , 0. , 0.4, 0.4, 0.8])
在最后一种情况下,将排名降低1,以使排名从0开始而不是从1开始。(我省略了“均值”,但是可以通过对后两种方法的结果求平均值来轻松获得。)
我做了一些时间。对于像您的示例这样的小数据,使用rankdata
的速度要比Kevin H.
Lin的解决方案要慢一些(大概是由于将东西转换成幕后的numpy数组会产生开销),但比像调用percentileofscore
reptilicus的那样循环调用要快:
In [11]: %timeit [stats.percentileofscore(x, i) for i in x]
1000 loops, best of 3: 414 µs per loop
In [12]: %timeit list_to_percentiles(x)
100000 loops, best of 3: 11.1 µs per loop
In [13]: %timeit stats.rankdata(x, "average")/len(x)
10000 loops, best of 3: 39.3 µs per loop
但是,对于大型数据集,numpy的性能优势会生效,使用rankdata
速度比Kevin快10倍list_to_percentiles
:
In [18]: x = np.random.randint(0, 10000, 1000)
In [19]: %timeit [stats.percentileofscore(x, i) for i in x]
1 loops, best of 3: 437 ms per loop
In [20]: %timeit list_to_percentiles(x)
100 loops, best of 3: 1.08 ms per loop
In [21]: %timeit stats.rankdata(x, "average")/len(x)
10000 loops, best of 3: 102 µs per loop
这种优势只会在越来越大的数据集上变得更加明显。
...但我得到: 我不知道如何应用这些信息。首先,我认为我需要为列表声明一些额外的映射(在同一个映射器类中),所以MapStruct知道如何像这样映射列表类型的每个字段: ...但我收到错误消息
问题内容: 基本上,这个问题是关于必须为6个值创建排列的数据。每个从1到38。 因此,第一个排列是 结束于 输出仅由6个嵌套循环创建,每个循环从1到38;在最内部的循环中,您将打印6个循环计数器。 现在我想知道其背后的数学原理;出于好奇:什么是“功能” 给定任意排列,计算“排列索引” 1 2 3 4 5 6 可能更有趣:它带有一个“索引”,例如102382;并告诉我相应的排列输出 有人知道吗?
问题内容: 我有一个FlagsAttribute按位枚举,像这样- 现在,在C#中,我将此值存储在一个名为MyProperty的属性中,并保存后将此属性写入我的SQL数据库的整数列中。假设如果我从代码中选择,那么它将在数据库中另存为。 我知道我可以从数据库获取值,只需要将int值类型转换为MyEnum,它将为我提供这些值。但是,我希望对某些存储过程中的SQL数据执行一些操作,在这些存储过程中,显然
我正在Play with Scala中开发一个REST服务器,在某些时候需要请求一个或多个其他Web服务的数据。根据这些服务的响应,服务器必须编写一个统一的结果供以后使用。 例子: 需要执行 上的事件 C。为了执行事件 C,还必须 上的事件 A 上的事件 B。 事件C有一个< code>Seq(www.anotherplace.com,www.athirdplace.com),我想从这个Seq开始
我有以下问题: 包含带有字符串 、 或 C 的 。 带有的第二个 。 以及其他三列 、 和 (这些列也命名为 、 和 )。 因此 应获得 现在我想遍历每一行,并根据 中的条目将 中的整数分配给列 A、B 或 C。 如何实现此目的? < code>df.withColumn()我不能使用(或者至少我不知道为什么),对于< code>val df2 = df.map(x = 提前期待您的帮助和感谢!
问题内容: 我正在尝试从DataFrame计算列中每个值的百分位数。 有没有更好的方法来编写以下代码? 我希望看到更好的性能。 问题答案: 似乎您想要: 性能: