اذهب إلى المحتوى

السؤال

نشر

هل هناك طريقة مناسبة لحساب قيمة percentile لمصفوفة معقدة أحادية البعد في مكتبة Numpy؟

أنا أبحث عن شيء مشابه للدالة المئوية percentile في Excel. لقد بحثت في مرجع Numpy، ولم أجد شيء يذكر حول هذا الأمر. كيف يمكنني القيام بهذا الأمر في Numpy؟

 

 

Recommended Posts

  • 2
نشر (معدل)

الطريقة الوحيدة في نمباي من خلال التابع percentile :

import numpy as np
arr = np.array([1,2,3,4,5])
# نريد القيمة الأكبر من نصف عناصر المصفوفة
per = np.percentile(arr, 50)
# 3.0
# القيمة الأكبر من 90 بالمئة من عناصر المصفوفة
np.percentile(arr, 90)
# 4.6
np.percentile(arr, 100)
# 5.0
np.percentile(arr, 0)
# 1.0

حيث نمرر له المصفوفة والنسبة المئوية التي نريده أن يرد لنا القيمة الموافقة لها. وإذا أردت أن يتم تقريب قيم الخرج لأقرب قيمة. أي مثلاً بدلاً من 4.6 تريد 4 أو 5 فيمكنك القيام بذلك كالتالي:

import numpy as np
arr = np.array([1,2,3,4,6])
np.percentile(arr, 90, interpolation='lower')
# 4
# التقريب للأعلى
np.percentile(arr, 90, interpolation='higher')
# 6

مثال آخر:

a = np.array([[10, 7, 4], [3, 2, 1]])
"""
array([[10,  7,  4],
       [ 3,  2,  1]])
"""
np.percentile(a, 50)
# 3.5
np.percentile(a, 50, axis=0)
# array([6.5, 4.5, 2.5])
np.percentile(a, 50, axis=1)
# array([7.,  2.])
np.percentile(a, 50, axis=0, out=out)
"""
array([6.5, 4.5, 2.5])
"""
np.percentile(a, 50, axis=1, keepdims=True)
"""
array([[7.],
       [2.]])
"""

حيث أن  الوسيط axis يمثل المحور أو المحاور التي سيتم حساب النسب المئوية على طولها. الافتراضي هو حساب النسب المئوية على طول نسخة مسطحة من المصفوفة.  أما الوسيط out فيمثل مصفوفة إخراج بديلة لوضع النتيجة فيها. يجب أن يكون له نفس الشكل وطول المخزن المؤقت للإخراج المتوقع ، ولكن سيتم إرسال نوع (الإخراج) إذا لزم الأمر.
ويمكنك من خلال التابع التالي القيام بذلك حيث سنستعين بالمكتبة الرياضية في بايثون:

import numpy as np
arr = np.array([1,2,3,4,5])
import math
def per(data, perc: int):
    return sorted(data)[int(math.ceil((len(data) * perc) / 100)) - 1]
per(arr,50)
# 3
per(arr,90)
# 5
# لاحظ أنه لم يعطي 4.6
per(arr,92)
# 5

لكن هنا كما تلاحظ قام بعملية تقريب بحيث تكون القيمة ضمن المصفوفة أي لن يحتسب مجالات القيم. ويمكنك أيضاً القيام بذلك من خلال التابع التالي:

import numpy as np
arr = np.array([1,2,3,4,5])
def per(N, P):
    n = int(round(P * len(N) + 0.5))
    return N[n-1]
per(arr,0.5)
# 3
per(arr,0.9)
# 5

 

تم التعديل في بواسطة Ali Haidar Ahmad
  • 0
نشر

يمكنك استخدام scipy.stats ونستخدم منه الدالة scoreatpercentile كالتالي

from scipy import stats
a = np.arange(100)
stats.scoreatpercentile(a, 50)
49.5

كما يمكنك استخدام python فقط بدون numpy أي مكتبات أخرى عن طريق تخصيص دالة تقوم بذلك

import math

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

ومثال 

percentile([10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0], 90)
# 9.0
percentile([142, 232, 290, 120, 274, 123, 146, 113, 272, 119, 124, 277, 207], 50)
# 146

 

  • 0
نشر

توجد دالة تابعة ل numpy يمكنها حساب ال percentile، ولها نفس الاسم، حيث تقوم بنفس الحسابات الموجوده في excel وتستخدم كالتالي:

# Python Program illustrating
# numpy.percentile() method
   
import numpy as np
   
# 1D array
arr = [20, 2, 7, 1, 34]
print("arr : ", arr)
print("50th percentile of arr : ",
       np.percentile(arr, 50))
print("25th percentile of arr : ",
       np.percentile(arr, 25))
print("75th percentile of arr : ",
       np.percentile(arr, 75))

كذلك يمكنك كتابة الدالة بنفسك كالتالي:

import math
import functools

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

    N - is a list of values. Note N MUST BE already sorted.
    percent - a float value from 0.0 to 1.0.
    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)

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...