मैं अजगर / सुन्न के साथ प्रतिशत की गणना कैसे करूं?


214

क्या अनुक्रम या एकल-आयामी सुपीरियर सरणी के लिए प्रतिशतक की गणना करने का एक सुविधाजनक तरीका है?

मैं एक्सेल के पर्सेंटाइल फ़ंक्शन के समान कुछ खोज रहा हूं।

मैंने NumPy के आंकड़ों के संदर्भ में देखा, और यह नहीं पाया। सभी मुझे मिल सकता है माध्यिका (50 वाँ प्रतिशत) है, लेकिन कुछ अधिक विशिष्ट नहीं है।


आवृत्तियों से प्रतिशतक की गणना पर एक संबंधित प्रश्न: stackoverflow.com/questions/25070086/…
newtover

जवाबों:


282

आपको SciPy Stats पैकेज में रुचि हो सकती है । यह आपके और उसके बाद कई अन्य सांख्यिकीय अच्छाइयों का प्रतिशत समारोह है

percentile() में numpyभी उपलब्ध है।

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

यह टिकट मुझे विश्वास percentile()दिलाता है कि वे जल्द ही कभी भी खस्ता नहीं होंगे ।


2
धन्यवाद! तो यह वह जगह है जहाँ यह छिपा हुआ है। मैं डरपोक था, लेकिन मुझे लगता है कि मैंने अनुमान लगाया है कि प्रतिशतक जैसी सरल चीजें सुन्न में बनाई जाएंगी।
उरई

16
अब तक, एक प्रतिशतक समारोह सुन्न में मौजूद है: docs.scipy.org/doc/numpy/reference/generated/…
एनाफोरी

1
आप इसे एग्रीगेशन फंक्शन के रूप में भी उपयोग कर सकते हैं, उदाहरण के लिए कुंजी कॉलम के प्रत्येक समूह के दसवें प्रतिशत को कुंजी द्वारा उपयोग करने के लिए, उपयोग करेंdf.groupby('key')[['value']].agg(lambda g: np.percentile(g, 10))
patricksurry

1
ध्यान दें कि SciPy NumPy 1.9 और उच्चतर के लिए np.percentile उपयोग करने के लिए सिफारिश की गई है
timdiels

73

वैसे, शत-प्रतिशत कार्य का शुद्ध-पायथन क्रियान्वयन होता है , अगर कोई स्किपी पर निर्भर नहीं होना चाहता है। फ़ंक्शन को नीचे कॉपी किया गया है:

## {{{ 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/ }}}

54
मैं उपरोक्त नुस्खा का लेखक हूं। ASPN में एक टिप्पणीकार ने बताया है कि मूल कोड में एक बग है। सूत्र d0 = कुंजी (N (int [f)]) * (ck) होना चाहिए; d1 = कुंजी (N [int (c)]) * (kf)। इसे ASPN पर सही किया गया है।
वाई वाई तुंग

1
कैसे percentileपता है कि किसके लिए उपयोग करना है N? यह फ़ंक्शन कॉल में निर्दिष्ट नहीं है।
रिचर्ड

14
उन लोगों के लिए, जिन्होंने कोड का उपयोग नहीं किया था, इसका उपयोग करने से पहले, एन को
छांटना

मैं लंबोदर अभिव्यक्ति से भ्रमित हूं। यह क्या करता है और यह कैसे करता है? मुझे पता है कि लैम्ब्डा अभिव्यक्ति क्या है इसलिए मैं यह नहीं पूछ रहा कि लैम्ब्डा क्या है। मैं पूछ रहा हूं कि यह विशिष्ट मेमना अभिव्यक्ति क्या करता है और यह कैसे कर रहा है, कदम-दर-कदम? धन्यवाद!
dsanchez

लैम्बडा फ़ंक्शन आपको Nप्रतिशतक की गणना करने से पहले डेटा को बदलने देता है । कहते हैं कि आपके पास वास्तव में टुपल्स की एक सूची है N = [(1, 2), (3, 1), ..., (5, 1)]और आप ट्यूपल्स के पहले तत्व का प्रतिशत प्राप्त करना चाहते हैं , फिर आप चुनते हैं key=lambda x: x[0]। आप प्रतिशतक की गणना करने से पहले सूची तत्वों में कुछ (क्रम-परिवर्तन) परिवर्तन भी लागू कर सकते हैं।
एलियास स्ट्रील


19

यहाँ यह कैसे सुन्न के बिना करने के लिए, केवल अजगर का उपयोग कर प्रतिशत गणना करने के लिए है।

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)

2
हां, आपको पहले सूची को क्रमबद्ध करना होगा: mylist = सॉर्ट किया गया (...)
अश्कां

12

प्रतिशतक की परिभाषा मुझे आमतौर पर दिखाई देती है जिसके परिणामस्वरूप आपूर्ति की गई सूची से मूल्य है जिसके नीचे P प्रतिशत मान पाए जाते हैं ... जिसका अर्थ है कि परिणाम सेट से होना चाहिए, न कि सेट तत्वों के बीच एक प्रक्षेप। इसे प्राप्त करने के लिए, आप एक सरल फ़ंक्शन का उपयोग कर सकते हैं।

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

यदि आपको आपूर्ति की गई सूची से या उसके नीचे मान मिलता है, जिसमें P प्रतिशत मान पाए जाते हैं, तो इस सरल संशोधन का उपयोग करें:

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

या @ijustlovemath द्वारा सुझाए गए सरलीकरण के साथ:

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

धन्यवाद, मैं भी सेट से वास्तविक मूल्यों के परिणाम के लिए प्रतिशत /
मंझले की

1
हाय @mpounsett ऊपरी कोड के लिए धन्यवाद। आपका प्रतिशत हमेशा पूर्णांक मान क्यों लौटाता है? प्रतिशतक फ़ंक्शन को मानों की सूची का N-th प्रतिशताइल वापस करना चाहिए, और यह एक फ्लोट संख्या भी हो सकती है। उदाहरण के लिए, एक्सेल PERCENTILEसमारोह अपने ऊपरी उदाहरण के लिए निम्नलिखित शतमक देता है: 3.7 = percentile(A, P=0.3), 0.82 = percentile(A, P=0.8), 20 = percentile(B, P=0.3), 42 = percentile(B, P=0.8)
मार्को

1
इसे पहले वाक्य में समझाया गया है। प्रतिशतक की अधिक सामान्य परिभाषा यह है कि यह एक श्रृंखला की संख्या है जिसके नीचे श्रृंखला में P प्रतिशत मान पाए जाते हैं। चूँकि किसी सूची में किसी आइटम का इंडेक्स नंबर है, यह फ्लोट नहीं हो सकता है।
mpounsett

यह 0'th प्रतिशतक के लिए काम नहीं करता है। यह अधिकतम मूल्य लौटाता है। एक फंक्शन n = int(...)में रैप करने के लिए एक जल्दी फिक्स होगाmax(int(...), 1)
22

स्पष्ट करने के लिए, क्या आपका मतलब दूसरे उदाहरण में है? मुझे अधिकतम मान के बजाय 0 मिलता है। बग वास्तव में अन्य खंड में है .. मैंने उस मूल्य के बजाय सूचकांक संख्या को मुद्रित किया था जिसका मैं इरादा था। अधिकतम () कॉल में 'n' के असाइनमेंट को रैप करना भी इसे ठीक कर देगा, लेकिन आप दूसरा मान 2 चाहते हैं, न कि 1. आप तब पूरी तरह से समाप्त कर सकते हैं यदि / अन्यथा संरचना और सिर्फ N का परिणाम प्रिंट करें [एन-2]। पहले उदाहरण में 0 वाँ प्रतिशतक ठीक काम करता है, क्रमशः '1' और '15' लौटाता है।
mpounsett

8

प्रारंभ Python 3.8, मानक पुस्तकालय मॉड्यूल के quantilesभाग के रूप में कार्य करता है statistics:

from statistics import quantiles

quantiles([1, 2, 3, 4, 5], n=100)
# [0.06, 0.12, 0.18, 0.24, 0.3, 0.36, 0.42, 0.48, 0.54, 0.6, 0.66, 0.72, 0.78, 0.84, 0.9, 0.96, 1.02, 1.08, 1.14, 1.2, 1.26, 1.32, 1.38, 1.44, 1.5, 1.56, 1.62, 1.68, 1.74, 1.8, 1.86, 1.92, 1.98, 2.04, 2.1, 2.16, 2.22, 2.28, 2.34, 2.4, 2.46, 2.52, 2.58, 2.64, 2.7, 2.76, 2.82, 2.88, 2.94, 3.0, 3.06, 3.12, 3.18, 3.24, 3.3, 3.36, 3.42, 3.48, 3.54, 3.6, 3.66, 3.72, 3.78, 3.84, 3.9, 3.96, 4.02, 4.08, 4.14, 4.2, 4.26, 4.32, 4.38, 4.44, 4.5, 4.56, 4.62, 4.68, 4.74, 4.8, 4.86, 4.92, 4.98, 5.04, 5.1, 5.16, 5.22, 5.28, 5.34, 5.4, 5.46, 5.52, 5.58, 5.64, 5.7, 5.76, 5.82, 5.88, 5.94]
quantiles([1, 2, 3, 4, 5], n=100)[49] # 50th percentile (e.g median)
# 3.0

quantilesदिए गए वितरण के लिए रिटर्न कट-पॉइंट distकी सूची को n - 1अलग करता है जो कि nक्वांटाइल अंतराल को अलग करता है ( समान संभावना वाले निरंतर अंतराल distमें विभाजन n)।

आंकड़े.क्वेंटाइल (डिस्ट, *, एन = 4, विधि = 'एक्सक्लूसिव')

जहां n, हमारे मामले में ( percentiles) है 100



2

किसी श्रृंखला की प्रतिशतता की गणना करने के लिए, दौड़ें:

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))

उदाहरण के लिए:

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}

1

मामले में आपको इनपुट के एक सदस्य होने के लिए उत्तर की आवश्यकता होती है:

बस यह जोड़ने के लिए कि डिफ़ॉल्ट रूप से सुन्न में प्रतिशतक फ़ंक्शन इनपुट वेक्टर में दो पड़ोसी प्रविष्टियों के रैखिक भारित औसत के रूप में आउटपुट की गणना करता है। कुछ मामलों में लोग चाहते हैं कि प्रतिशतक वेक्टर का एक वास्तविक तत्व हो सकता है, इस मामले में, v1.9.0 से आप "इंटरपोलेशन" विकल्प का उपयोग कर सकते हैं, या तो "कम", "उच्च" या "निकटतम"।

import numpy as np
x=np.random.uniform(10,size=(1000))-5.0

np.percentile(x,70) # 70th percentile

2.075966046220879

np.percentile(x,70,interpolation="nearest")

2.0729677997904314

उत्तरार्द्ध वेक्टर में एक वास्तविक प्रविष्टि है, जबकि पूर्व दो वेक्टर प्रविष्टियों का एक रेखीय प्रक्षेप है जो प्रतिशतक की सीमा करता है


0

एक श्रृंखला के लिए: वर्णित कार्यों का उपयोग किया

मान लें कि आपके पास कॉलम बिक्री और आईडी के साथ df है। आप बिक्री के लिए प्रतिशत की गणना करना चाहते हैं तो यह इस तरह काम करता है,

df['sales'].describe(percentiles = [0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1])

0.0: .0: minimum
1: maximum 
0.1 : 10th percentile and so on

0

एक आयामी संख्यात्मक अनुक्रम या मैट्रिक्स के लिए प्रतिशत की गणना करने का एक सुविधाजनक तरीका numpy.percentile < https://docs.scipy.org/doc/numpy/reference/generated/numpy.percentile.html > का उपयोग करके है । उदाहरण:

import numpy as np

a = np.array([0,1,2,3,4,5,6,7,8,9,10])
p50 = np.percentile(a, 50) # return 50th percentile, e.g median.
p90 = np.percentile(a, 90) # return 90th percentile.
print('median = ',p50,' and p90 = ',p90) # median =  5.0  and p90 =  9.0

हालांकि, यदि आपके डेटा में कोई NaN मान है, तो उपरोक्त फ़ंक्शन उपयोगी नहीं होगा। उस मामले में उपयोग करने के लिए अनुशंसित फ़ंक्शन numpy.nanpercentile < https://docs.scipy.org/doc/numpy/reference/generated/numpy.nanpercentile.html > फ़ंक्शन है:

import numpy as np

a_NaN = np.array([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.])
a_NaN[0] = np.nan
print('a_NaN',a_NaN)
p50 = np.nanpercentile(a_NaN, 50) # return 50th percentile, e.g median.
p90 = np.nanpercentile(a_NaN, 90) # return 90th percentile.
print('median = ',p50,' and p90 = ',p90) # median =  5.5  and p90 =  9.1

ऊपर प्रस्तुत दो विकल्पों में, आप अभी भी प्रक्षेप मोड का चयन कर सकते हैं। आसान समझ के लिए नीचे दिए गए उदाहरणों का पालन करें।

import numpy as np

b = np.array([1,2,3,4,5,6,7,8,9,10])
print('percentiles using default interpolation')
p10 = np.percentile(b, 10) # return 10th percentile.
p50 = np.percentile(b, 50) # return 50th percentile, e.g median.
p90 = np.percentile(b, 90) # return 90th percentile.
print('p10 = ',p10,', median = ',p50,' and p90 = ',p90)
#p10 =  1.9 , median =  5.5  and p90 =  9.1

print('percentiles using interpolation = ', "linear")
p10 = np.percentile(b, 10,interpolation='linear') # return 10th percentile.
p50 = np.percentile(b, 50,interpolation='linear') # return 50th percentile, e.g median.
p90 = np.percentile(b, 90,interpolation='linear') # return 90th percentile.
print('p10 = ',p10,', median = ',p50,' and p90 = ',p90)
#p10 =  1.9 , median =  5.5  and p90 =  9.1

print('percentiles using interpolation = ', "lower")
p10 = np.percentile(b, 10,interpolation='lower') # return 10th percentile.
p50 = np.percentile(b, 50,interpolation='lower') # return 50th percentile, e.g median.
p90 = np.percentile(b, 90,interpolation='lower') # return 90th percentile.
print('p10 = ',p10,', median = ',p50,' and p90 = ',p90)
#p10 =  1 , median =  5  and p90 =  9

print('percentiles using interpolation = ', "higher")
p10 = np.percentile(b, 10,interpolation='higher') # return 10th percentile.
p50 = np.percentile(b, 50,interpolation='higher') # return 50th percentile, e.g median.
p90 = np.percentile(b, 90,interpolation='higher') # return 90th percentile.
print('p10 = ',p10,', median = ',p50,' and p90 = ',p90)
#p10 =  2 , median =  6  and p90 =  10

print('percentiles using interpolation = ', "midpoint")
p10 = np.percentile(b, 10,interpolation='midpoint') # return 10th percentile.
p50 = np.percentile(b, 50,interpolation='midpoint') # return 50th percentile, e.g median.
p90 = np.percentile(b, 90,interpolation='midpoint') # return 90th percentile.
print('p10 = ',p10,', median = ',p50,' and p90 = ',p90)
#p10 =  1.5 , median =  5.5  and p90 =  9.5

print('percentiles using interpolation = ', "nearest")
p10 = np.percentile(b, 10,interpolation='nearest') # return 10th percentile.
p50 = np.percentile(b, 50,interpolation='nearest') # return 50th percentile, e.g median.
p90 = np.percentile(b, 90,interpolation='nearest') # return 90th percentile.
print('p10 = ',p10,', median = ',p50,' and p90 = ',p90)
#p10 =  2 , median =  5  and p90 =  9

यदि आपके इनपुट सरणी में केवल पूर्णांक मान शामिल हैं, तो आप पूर्णांक उत्तर में पूर्णांक के रूप में रुचि ले सकते हैं। यदि हां, तो इंटरपोलेशन मोड जैसे 'लोअर', 'हायर', या 'निकटतम' चुनें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.