2010-03-03 60 views
135

Có cách nào thuận tiện để tính toán phần trăm cho một mảng numpy chuỗi hoặc một chiều không?Làm cách nào để tính phần trăm với python/numpy?

Tôi đang tìm một cái gì đó tương tự như chức năng phần trăm của Excel.

Tôi đã xem số liệu thống kê của NumPy tham chiếu và không thể tìm thấy thông tin này. Tất cả những gì tôi có thể tìm thấy là trung bình (50 phần trăm), nhưng không phải là một cái gì đó cụ thể hơn.

Trả lời

182

Bạn có thể quan tâm đến gói SciPy Stats. Nó có the percentile function bạn đang theo dõi và nhiều tính năng thống kê khác.

percentile()is available trong numpy quá.

import numpy as np 
a = np.array([1,2,3,4,5]) 
p = np.percentile(a, 50) # return 50th percentile, e.g median. 
print p 
3.0 

This ticket dẫn tôi để tin rằng họ sẽ không được tích hợp vào percentile() NumPy bất cứ lúc nào sớm.

+2

Cảm ơn bạn! Vì vậy, đó là nơi nó được cất giấu. Tôi đã nhận thức được scipy nhưng tôi đoán tôi giả định những thứ đơn giản như phần trăm sẽ được xây dựng thành gumpy. – Uri

+14

Hiện tại, hàm phần trăm tồn tại ở dạng gumpy: http://docs.scipy.org/doc/numpy/reference/generated/numpy.percentile.html – Anaphory

+1

Bạn cũng có thể sử dụng hàm này làm hàm tổng hợp, ví dụ: để tính phần trăm thứ mười của mỗi nhóm của cột giá trị theo khóa, sử dụng 'df.groupby ('key') [['value']]. agg (lambda g: np.percentile (g, 10))' – patricksurry

51

Nhân tiện, có a pure-Python implementation of percentile function, trong trường hợp một người không muốn phụ thuộc vào scipy. Các chức năng được sao chép dưới đây:

## {{{ http://code.activestate.com/recipes/511478/ (r1) 
import math 
import functools 

def percentile(N, percent, key=lambda x:x): 
    """ 
    Find the percentile of a list of values. 

    @parameter N - is a list of values. Note N MUST BE already sorted. 
    @parameter percent - a float value from 0.0 to 1.0. 
    @parameter key - optional key function to compute value from each element of N. 

    @return - the percentile of the values 
    """ 
    if not N: 
     return None 
    k = (len(N)-1) * percent 
    f = math.floor(k) 
    c = math.ceil(k) 
    if f == c: 
     return key(N[int(k)]) 
    d0 = key(N[int(f)]) * (c-k) 
    d1 = key(N[int(c)]) * (k-f) 
    return d0+d1 

# median is 50th percentile. 
median = functools.partial(percentile, percent=0.5) 
## end of http://code.activestate.com/recipes/511478/ }}} 
+39

Tôi là tác giả của công thức trên.Một người bình luận trong ASPN đã chỉ ra rằng mã gốc có một lỗi. Công thức phải là d0 = khóa (N [int (f)]) * (c-k); d1 = khóa (N [int (c)]) * (k-f). Nó đã được sửa chữa trên ASPN. –

+6

@Wai Yip Tung, tôi đã sửa lỗi trong mã số –

+1

'percentile' biết phải sử dụng gì cho' N'? Nó không được chỉ định trong lời gọi hàm. – Richard

7

séc cho module scipy.stats:

scipy.stats.scoreatpercentile 
8

Định nghĩa của percentile Tôi thường nhìn thấy hy vọng kết quả là giá trị từ danh sách được cung cấp dưới đây mà P phần trăm của giá trị được tìm thấy ... có nghĩa là kết quả phải từ tập hợp, không phải là nội suy giữa các phần tử đã đặt. Để có được điều đó, bạn có thể sử dụng một hàm đơn giản hơn.

def percentile(N, P): 
    """ 
    Find the percentile of a list of values 

    @parameter N - A list of values. N must be sorted. 
    @parameter P - A float value from 0.0 to 1.0 

    @return - The percentile of the values. 
    """ 
    n = int(round(P * len(N) + 0.5)) 
    return N[n-1] 

# A = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) 
# B = (15, 20, 35, 40, 50) 
# 
# print percentile(A, P=0.3) 
# 4 
# print percentile(A, P=0.8) 
# 9 
# print percentile(B, P=0.3) 
# 20 
# print percentile(B, P=0.8) 
# 50 

Nếu bạn muốn nhận được giá trị từ danh sách được cung cấp bằng hoặc thấp hơn mà P phần trăm của giá trị được tìm thấy, sau đó sử dụng sửa đổi đơn giản này:

def percentile(N, P): 
    n = int(round(P * len(N) + 0.5)) 
    if n > 1: 
     return N[n-2] 
    else: 
     return N[0] 

Hoặc với đơn giản hóa được đề xuất bởi @ijustlovemath :

def percentile(N, P): 
    n = max(int(round(P * len(N) + 0.5)), 2) 
    return N[n-2] 
+0

cảm ơn, tôi cũng mong đợi phần trăm/trung bình để kết quả giá trị thực tế từ các bộ và không nội suy – hansaplast

+0

Hi @mpounsett. Cảm ơn bạn đã viết mã trên. Tại sao phần trăm của bạn luôn trả về các giá trị số nguyên? Hàm phần trăm sẽ trả về phần trăm N của một danh sách các giá trị, và đây cũng có thể là một số phao. Ví dụ, hàm Excel '' 'PERCENTILE''' trả về các phần trăm sau cho các ví dụ trên của bạn:' '' 3.7 = percentile (A, P = 0.3) '' ',' '' 0.82 = percentile (A, P = 0,8) '' ',' '' 20 = phần trăm (B, P = 0,3) '' ',' '' 42 = phần trăm (B, P = 0,8) '' '. – marco

+0

Nó được giải thích trong câu đầu tiên. Định nghĩa phân vị phổ biến hơn là nó là số trong một chuỗi bên dưới mà P phần trăm của các giá trị trong chuỗi được tìm thấy. Vì đó là số chỉ mục của một mục trong một danh sách, nó không thể là một phao. – mpounsett

5

Dưới đây là cách thực hiện điều đó mà không cần sần, chỉ sử dụng python để tính phần trăm.

import math 

def percentile(data, percentile): 
    size = len(data) 
    return sorted(data)[int(math.ceil((size * percentile)/100)) - 1] 

p5 = percentile(mylist, 5) 
p25 = percentile(mylist, 25) 
p50 = percentile(mylist, 50) 
p75 = percentile(mylist, 75) 
p95 = percentile(mylist, 95) 
+0

điều này sẽ chỉ hoạt động nếu dữ liệu được đặt hàng – otmezger

+2

Có, bạn phải sắp xếp danh sách trước: mylist = sắp xếp (...) – Ashkan

23
import numpy as np 
a = [154, 400, 1124, 82, 94, 108] 
print np.percentile(a,95) # gives the 95th percentile 
0

Để tính toán phần trăm của một loạt, chạy:

from scipy.stats import rankdata 
import numpy as np 

def calc_percentile(a, method='min'): 
    if isinstance(a, list): 
     a = np.asarray(a) 
    return rankdata(a, method=method)/float(len(a)) 

Ví dụ:

a = range(20) 
print {val: round(percentile, 3) for val, percentile in zip(a, calc_percentile(a))} 
>>> {0: 0.05, 1: 0.1, 2: 0.15, 3: 0.2, 4: 0.25, 5: 0.3, 6: 0.35, 7: 0.4, 8: 0.45, 9: 0.5, 10: 0.55, 11: 0.6, 12: 0.65, 13: 0.7, 14: 0.75, 15: 0.8, 16: 0.85, 17: 0.9, 18: 0.95, 19: 1.0} 
Các vấn đề liên quan