আমি কীভাবে পাইথন / নিমপি দিয়ে পার্সেন্টাইলগুলি গণনা করব?


214

কোন সিকোয়েন্স বা একক-মাত্রিক নিমপী অ্যারের জন্য পারসেন্টাইলগুলি গণনা করার কোনও সুবিধাজনক উপায় নেই?

আমি এক্সেলের পারসেন্টাইল ফাংশনের অনুরূপ কিছু সন্ধান করছি।

আমি নম্পপির পরিসংখ্যানের রেফারেন্সটি দেখেছিলাম এবং এটি খুঁজে পেলাম না। আমি যা খুঁজে পেতে পারি তা হ'ল মিডিয়ান (50 তম পারসেন্টাইল), তবে এর চেয়ে নির্দিষ্ট কিছু নয়।


ফ্রিকোয়েন্সি থেকে শতকরা এর গণনার ওপর সংশ্লিষ্ট প্রশ্ন: stackoverflow.com/questions/25070086/...
newtover

উত্তর:


282

আপনি হয়ত সাইপি স্ট্যাটাস প্যাকেজটিতে আগ্রহী। এটির পরে রয়েছে পারসেন্টাইল ফাংশন এবং অন্যান্য অনেক পরিসংখ্যানগত গুড।

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
: এখন, একটি শতকরা ফাংশনে numpy বিদ্যমান docs.scipy.org/doc/numpy/reference/generated/...
Anaphory

1
আপনি ভাল হিসাবে একটি অ্যাগ্রিগেশন ফাংশন হিসাবে এটি ব্যবহার করতে পারেন, যেমন দ্বারা কী, ব্যবহার একটি মান কলামের প্রতিটি গ্রুপের শতকরা দশম গনাdf.groupby('key')[['value']].agg(lambda g: np.percentile(g, 10))
patricksurry

1
নোট করুন যে সায়পাই NumPy 1.9 এবং উচ্চতর জন্য np.percentile ব্যবহার করার পরামর্শ দিয়েছেন
টাইমডিয়েল

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
আমি উপরের রেসিপিটির লেখক am এএসপিএন-তে একজন মন্তব্যকারী মূল কোডটিতে একটি বাগ রয়েছে তা নির্দেশ করেছে। সূত্রটি d0 = কী (N [int (f)]) * (সিকে) হওয়া উচিত; d1 = কী (এন [ইনট (সি))] * (কেএফ)। এটিএসপিএন-তে সংশোধন করা হয়েছে।
ওয়াই ইপ টুং

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 = সাজানো (...): হ্যাঁ, আপনি তালিকা বাছাই করার আগে আছে
Ashkan

12

শতভাগের সংজ্ঞাটি আমি সাধারণত দেখতে পাই ফলস্বরূপ সরবরাহ করা তালিকার মান যার নীচে পি শতাংশের সন্ধান পাওয়া যায় তার প্রত্যাশা করে ... যার অর্থ ফলাফল অবশ্যই সেট থেকে হওয়া উচিত, সেট উপাদানগুলির মধ্যে কোনও বিভাজন নয়। এটি পেতে, আপনি একটি সহজ ফাংশন ব্যবহার করতে পারেন।

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

যদি আপনি পরিবর্তিত সরবরাহিত তালিকার নীচে বা তার চেয়ে নীচে পি শতাংশের মান খুঁজে পেতে চান তবে এই সাধারণ পরিবর্তনটি ব্যবহার করুন:

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

বা @justlovemath দ্বারা প্রস্তাবিত সরলকরণ সহ:

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

ধন্যবাদ, আমি আশা করি পারসেন্টাইল / মিডিয়ানও সেটগুলি থেকে প্রকৃত মানগুলিকে ফলাফল দেবে এবং
বিরক্তি

1
হাই @ এমপাউনসেট উপরের কোডের জন্য আপনাকে ধন্যবাদ। আপনার শতকরা কেন সর্বদা পূর্ণসংখ্যার মানগুলি ফেরত দেয়? পারসেন্টাইল ফাংশনটি মানগুলির তালিকার 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
এটি প্রথম বাক্যে ব্যাখ্যা করা হয়েছে। পারসেন্টাইলের আরও সাধারণ সংজ্ঞাটি হ'ল এটি একটি সিরিজের এমন নম্বর যা নীচে সিরিজের পি শতাংশের মান পাওয়া যায়। যেহেতু এটি কোনও তালিকার কোনও আইটেমের সূচক সংখ্যা, এটি ভাসা হতে পারে না।
এমপুনসেট

এটি 0 তম পার্সেন্টাইলের জন্য কাজ করে না। এটি সর্বাধিক মান প্রদান করে। একটি দ্রুত সমাধান n = int(...)max(int(...), 1)
হ'ল

স্পষ্ট করে বলতে গেলে, আপনি কি দ্বিতীয় উদাহরণটির অর্থ বোঝাতে চান? আমি সর্বোচ্চ মানের চেয়ে 0 পাই rather বাগটি অন্য শর্তে আসলে .. আমি যে মানটি চেয়েছি তার পরিবর্তে সূচি নম্বরটি প্রিন্ট করেছি। সর্বাধিক () কলটিতে 'এন' এর কার্যক্রিয়াটি মোড়ানোও এটি ঠিক করে দেবে, তবে আপনি দ্বিতীয় মানটি 2 না হতে চান 1 এর চেয়ে বেছে নিতে পারেন তবে আপনি / অন্য কাঠামোটি পুরোটি মুছে ফেলতে পারতেন এবং কেবল এন এর ফলাফল মুদ্রণ করতে পারবেন [এন-2]। 0 তম পার্সেন্টাইল প্রথম উদাহরণে সূক্ষ্মভাবে কাজ করে যথাক্রমে '1' এবং '15' ফেরত।
এমপাউনেসেট

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


6

scipy.stats মডিউল জন্য পরীক্ষা করুন:

 scipy.stats.scoreatpercentile

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

দ্বিতীয়টি ভেক্টরটিতে একটি আসল প্রবেশ, যখন পূর্ববর্তীটি দুটি ভেক্টর এন্ট্রিগুলির লিনিয়ার ইন্টারপোলেশন যা পারসেন্টাইলের সীমানা হয় border


0

একটি সিরিজের জন্য: ব্যবহৃত ফাংশন বর্ণনা

ধরুন আপনার নীচের কলামগুলির বিক্রয় এবং আইডি রয়েছে। আপনি বিক্রয়ের জন্য শতকরা হিসাব করতে চান তবে এটি এর মতো কাজ করে,

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.percentil < https://docs.scipy.org/doc/numpy/references/generated/numpy.percentil.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

তবে আপনার ডেটাতে যদি কোনও এনএএন মান থাকে তবে উপরের ফাংশনটি কার্যকর হবে না। সেক্ষেত্রে ব্যবহার করার জন্য প্রস্তাবিত ফাংশনটি হ'ল numpy.nanpercentile < https://docs.scipy.org/doc/numpy/references/generated/numpy.nanpercentil.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

যদি আপনার ইনপুট অ্যারেতে কেবল পূর্ণসংখ্যার মান থাকে তবে আপনি পূর্ণসংখ্যা হিসাবে পার্সেন্টিল উত্তরে আগ্রহী হতে পারেন। যদি তা হয় তবে ইন্টারপোলেশন মোড যেমন 'নিম্ন', 'উচ্চতর', বা 'নিকটতম' চয়ন করুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.