Numpy: إعادة هيكلة الطرق المئوية

تم إنشاؤها على ١٢ مارس ٢٠١٨  ·  53تعليقات  ·  مصدر: numpy/numpy

كما هو موضح في صفحة Wikipedia: https://en.wikipedia.org/wiki/Percentile#The_nearest -rank_method

00 - Bug 01 - Enhancement high

ال 53 كومينتر

أعتقد أن هذا موجود بالفعل؟ باستخدام مثال ويكيبيديا:

>>> np.percentile(15, 20, 35, 40, 50], [5, 30, 40, 50, 100], interpolation='lower')
array([15, 20, 20, 35, 50])

لم يحدث ذلك. انظر إلى المثال 2 في صفحة ويكيبيديا:

>>> np.percentile([3, 6, 7, 8, 8, 10, 13, 15, 16, 20], [25,50,75,100], interpolation='lower')
array([ 7,  8, 13, 20])

متى يجب أن يكون [7,8,15,20]

فشل بالمثل في المثال الثالث

الأقرب يبدو كثيرًا مثل "الأقرب"؟ على الرغم من وجود نقطة أخرى حول كيفية عمل الحدود بالضبط.
تحرير: هذا هو ، أين بالضبط يتم اعتبار 0 و 100 ، عند نقطة البيانات أو قبل نقطة البيانات؟ (هذا هو IIRC ، على أي حال ، هناك الكثير من التعقيدات المزعجة هنا)

لا ترغب في قراءتها ، أعتقد أن الاختلاف قد يكون المعلمة C في الأسفل ، لذلك إذا أراد شخص يعرف هذا إضافة هذا ...

بصراحة ، أعتقد أن إضافة المعامل C سيكون جيدًا على الأرجح. لكن في الغالب سيكون التوثيق الأفضل أمرًا رائعًا ، وهناك حاجة إلى شخص يعرف هذه الأشياء حقًا ...

لا أعرف ما إذا كان هذا له علاقة بالمعامل C ، على الرغم من أنني أوافق على أن خيار اختياره قد يكون مرغوبًا فيه.

لقد وجدت آخر موضوع الذي جاء بالمناسبة هذه المسألة (2016 ديسمبر). يبدو أن الخوارزمية التي أبحث عنها (والتي تسميها ويكيبيديا أقرب رتبة) مذكورة في هذه الورقة التي يُستشهد بها بشكل شائع

إليك كيف سيبدو الأمر مقابل الخيارات الأخرى التي يوفرها numpy والتي تبدو بديهية أنها تحسب شيئًا مشابهًا (على سبيل المثال ، "أقل" ، "أقرب"):

percentiles

بالنسبة لي ، يبدو تمامًا مثل المعلمة C للوهلة الأولى ، فإن أقرب منحنى أكثر تمددًا ثم منحنى H&F ، وهو أمر متوقع لأن numpy يستخدم 1 ويبدو أن H&F يستخدم 0.

إذا كنت تريد الدليل. كرر الأمر برمته بنفس القيم التي تكررت 1000 مرة ، أعتقد أنها ستتقارب.
تحرير: أو ربما لا ، ليس لديك الصبر أو الوقت للتفكير في الأمر حقًا. لكنني ما زلت أعتقد أن المعلمة C مذكورة في ويكيبيديا ، لذا يرجى إثبات خطأ لي :)

سيكون رسمًا بيانيًا كهذا إضافة رائعة للمستندات المئوية

تحرير: يفضل أن يكون واحدًا يظهر انفتاح / انغلاق الانقطاعات

ملاحظة للقراء: للإبقاء على هذا الموضوع قابلاً للإدارة ، قمت بتمييز جميع المناقشات أدناه حول إضافة هذا الرسم البياني إلى المستندات على أنها "تم حلها". يوجد الرسم البياني الآن في الجزء السفلي من https://numpy.org/devdocs/reference/generated/numpy.percentile.html.

@ eric-wieser لا أمانع في عمل هذا الرسم البياني. سأعود بشيء ما لاحقًا اليوم ، هل يجب أن أنشره هنا؟

seberg سأكون صادقًا هنا ، لا أعرف كيف يتم حساب الاستيفاء بناءً على المعلمة C. ما يجعلني أعتقد أنه غير مرتبط هو أن المعلمة C تتم مناقشتها فقط في قسم الاستيفاء الخطي (Wikipedia) ، وتناقش كل من Wikipedia و Hyndmand & Fan الورقة البحثية الخوارزمية التي طلبتها في أقسام منفصلة من أقسام الاستيفاء.

لا أعرف ما إذا كانت هناك أي معلمات استيفاء تعطي دائمًا نفس النتائج مثل الخوارزمية التي أهتم بها.

حتى لو كان هناك ، هل يجب أن تكون هذه هي الطريقة المستخدمة للوصول إليها؟ لا يبدو أن تغيير المعامل "الغريب" للحصول على التعريف الأكثر شيوعًا للنسب المئوية هو أفضل طريقة لتطبيقه.

@ ricardoV94 ، ربما ، لكن لا يمكنك فقط تغيير الإعدادات الافتراضية ، مهما كانت سيئة. يمكننا الكشف عن شيء مثل الطريقة = "H&K" لتجاوز كلا المعلمتين في وقت واحد.

معلمات C هي المكان الذي تحدد فيه 0٪ و 100٪ بالنسبة لنقاط البيانات (في نقطة البيانات أم لا ، وما إلى ذلك). كمعامل C على ويكيبيديا ، قد يكون من أجل الاستيفاء فقط ، لكن المشكلة نفسها تسبب الاختلاف هنا أنا متأكد. C مشكوك فيه بالطبع ، قد يكون الاسم الصحيح شيئًا مثل range = 'min-max' أو range = 'extrapolated' أو ربما شيئًا مختلفًا تمامًا. كما قلت ، أعد رسم المؤامرات بالعديد من نقاط البيانات (ربما مع ضوضاء صغيرة) ، وأعتقد أنك ستراهم يتقاربون ، لأن تعريف النطاق يصبح أقل وضوحًا.

seberg أنا بخير مع الطريقة = "H&K" أو ربما الطريقة = "الكلاسيكية". الاستيفاء = "لا شيء" يمكن أن يكون له معنى أيضًا.

لست متأكدًا من آلية تضمين الصور في المستندات ، أو ما إذا كانت هناك سابقة للقيام بذلك.

أعلم أنه يمكنك تشغيل كود matplotlib داخل المستندات ، وهي الطريقة التي نقوم بها في مكان آخر - مما يضمن أيضًا استمرار مزامنتها مع الواقع.

حسنًا ، سأفكر في أفضل صورة رمز في هذه الحالة.

الجزء الأكثر إشكالية هو العلامات المفتوحة والمغلقة للانقطاع ، نظرًا لأن matplotlib لا يحتوي على وظيفة مضمنة لذلك (afaik). الترميز الصارم لهم لن يكون له معنى في هذه الحالة.

ربما تخطي هؤلاء الآن بعد ذلك. سيكون من الرائع أن يكون لدى matplotlib بعض الدعم التلقائي لهؤلاء.

نأمل أن يكون لدى شخص ما اقتراح أفضل ، والذي لا يزال أنيقًا فيما يتعلق بالانقطاع.

import matplotlib.pyplot as plt

a = [0,1,2,3]
p = np.arange(101)

plt.step(p, np.percentile(a, p, interpolation='linear'), label='linear')
plt.step(p, np.percentile(a, p, interpolation='higher'), label='higher', linestyle='--')
plt.step(p, np.percentile(a, p, interpolation='lower'), label='lower', linestyle='--')
plt.step(p, np.percentile(a, p, interpolation='nearest'), label='nearest', linestyle='-.',)
plt.step(p, np.percentile(a, p, interpolation='midpoint'), label='midpoint', linestyle='-.',)

plt.title('Interpolation methods for list: ' + str(a))
plt.xlabel('Percentile')
plt.ylabel('List item returned')
plt.yticks(a)
plt.legend()

Image

أعتقد أن interpolation = 'linear' يجب أن يكون خطًا عاديًا غير متدرج ، ولكن بخلاف ذلك يبدو جيدًا. هل يمكنك عمل علاقات عامة مع إضافة ذلك إلى المستندات؟

في الواقع ، يتسبب step حدوث مصنوعات مضللة بشكل عام ، لذلك سأميل إلى تجنبها. سينتج linspace(0, 100, 60) إحداثيات وسيطة أكثر دقة أيضًا

ليس لدي أي فكرة عن كيفية عمل العلاقات العامة.

لا تتردد في القيام بذلك مع حسابك ، إضافة أو مناقشة التغييرات المقترحة.

أعتقد أنه يمكنك تغيير C بشيء من هذا القبيل (جربه على شيء ما). قم باستدعاء الوظيفة على النسب المئوية الخاصة بك ، ثم قم بتوصيلها بالإصدار numpy (الذي يستخدم C = 1 ، وهو أمر غير متاح باستثناء تصحيح النسب المئوية المقيدة الآن):

def scale_percentiles(p, num, C=0):
     """
     p : float
          percentiles to be used (within 0 and 100 inclusive)
     num : int
         number of data points.
     C : float
         parameter C, should be 0, 0.5 or 1. Numpy uses 1, matlab 0.5, H&K is 0.
     """
     p = np.asarray(p)
     fact = (num-1.+2*C)/(num-1)
     p *= fact
     p -= 0.5 * (fact-1) * 100
     p[p < 0] = 0
     p[p > 100] = 100
     return p

وفويلا ، مع كلمة "الأقرب" ستحصل على "H&F" ومع الخطية ستحصل على الحبكة من ويكيبيديا. (ريثما أفهمت شيئًا خاطئًا ، لكنني متأكد من أنني فهمته بشكل صحيح).

كما قلت ، الاختلاف هو المكان الذي تضع فيه نقاط البيانات من 0-100 (بالتساوي) فيما يتعلق بالنقطة الأخيرة. بالنسبة لـ C = 1 ، تضع min (البيانات) إلى النسبة المئوية 0 ، وما إلى ذلك. ليس لدي أدنى فكرة عن "ما هو أكثر منطقية" ، فمن المحتمل أن يكون الأمر مهمًا قليلاً من العرض العام. إن الاسم المتضمن لـ 1 والحصري لـ 0 منطقي بعض الشيء على ما أعتقد (عندما تفكر في النطاق الإجمالي للنسب المئوية ، نظرًا لأن النطاق المحتمل يكون خارج نطاق البيانات). C = 1/2 هي أيضًا حصرية بهذا المعنى.

سأكون لإضافة المعلمة C ، لكني أريد أن يأتي شخص ما باسم وصفي إن أمكن. لا أمانع أيضًا في شيء مثل "طريقة" أو ما شابه ذلك لجعل أفضل القيم الافتراضية واضحة (مزيج من الاستيفاء + C). أو ، قررنا بشكل أساسي أن معظم التركيبات لا تُستخدم أبدًا وليست مفيدة ، حسنًا ...

في النهاية ، مشكلتي هي: أريد من الإحصائي أن يخبرني بالطرق التي لديها إجماع (لدى R بعض الأشياء ، لكن آخر مرة جاء فيها شخص ما هنا كانت مجرد نسخة سابقة من مستند R أو ما شابه دون وضعها في سياق فارغ في كل شيء ، وغني عن القول ، كان عديم الفائدة للجمهور العام ، وكان الاستشهاد بالأوراق البحثية سيكون أكثر فائدة).

لا أريد أن أقرأ ورقة H&F هذه (بصراحة ، لا تبدو أيضًا سهلة القراءة) ، ولكن أعتقد أنه يمكنك النظر إليها من وجهة نظر الدعم أيضًا. لا يحتوي الإصدار "الأقرب" (أو أي إصدار آخر) على دعم متطابق (في النسب المئوية) لكل نقطة بيانات ، ولدى H&F دعم متساوٍ لـ "الأقرب" وربما لنقطة الوسط سيكون C = 1/2 ، غير متأكد.
ما زلت أكرر نفسي ، لا أعرف ما إذا كانت حجة الدعم هذه (ضد C = 1 مثل استخدامها numpy) ، هي في الواقع سبب حقيقي.

تحرير: نقطة المنتصف لها دعم متساوٍ (للمنطقة الواقعة بين نقاط البيانات ، وليس للنقطة نفسها) في numpy ، لذلك مع "C = 1"

seberg لا يبدو أنه يعمل معي. هل يمكنك نشر الرمز الخاص بك يظهر أنه يعمل؟

حسنًا ، لقد أخطأت في الإشارة ، في هذا الرمز هناك ، لذلك كانت معاكسة (C = 0 a no-op وليس C = 1):

def scale_percentiles(p, num, C=0):
     """
     p : float
          percentiles to be used (within 0 and 100 inclusive)
     num : int
         number of data points.
     C : float
         parameter C, should be 0, 0.5 or 1. Numpy uses 1, matlab 0.5, H&F is 0.
     """
     p = np.asarray(p)
     fact = (num+1.-2*C)/(num-1)
     p *= fact
     p -= 0.5 * (fact-1) * 100
     p[p < 0] = 0
     p[p > 100] = 100
     return p
plt.figure()
plt.plot(np.percentile([0, 1, 2, 3], scale_percentiles(np.linspace(0, 100, 101), 5, C=0), interpolation='nearest'))
plt.plot(np.percentile([0, 1, 2, 3], scale_percentiles(np.linspace(0, 100, 101), 5, C=1), interpolation='nearest'))
plt.figure()
plt.plot(np.percentile([15, 20, 35, 40, 50], scale_percentiles(np.linspace(0, 100, 101), 5, C=1), interpolation='linear'))
plt.plot(np.percentile([15, 20, 35, 40, 50], scale_percentiles(np.linspace(0, 100, 101), 5, C=0.5), interpolation='linear'))
plt.plot(np.percentile([15, 20, 35, 40, 50], scale_percentiles(np.linspace(0, 100, 101), 5, C=0), interpolation='linear'))

seberg إغلاق ولكن ليس هناك بعد. بالنسبة إلى a = [0,1,2,3] و percentiles = [25, 50, 75, 100] ، تُرجع [0, 2, 3, 3] np.percentile (a, scale_percentiles(percentiles, len(a), C=0), interpolation='nearest) [0, 2, 3, 3] ، عندما تُرجع [0,1,2,3] .

اضطررت إلى جعل القائمة المئوية dtype=np.float أو ستعطي وظيفتك خطأ ، لكنني لا أعتقد أن هذه هي المشكلة.

وظيفة الطريقة الكلاسيكية بسيطة:
النسبة المئوية / 100 * N -> إذا كان رقمًا صحيحًا يمثل الفهرس ، وإذا لم يكن كذلك ، فاستخدم السقف كمؤشر.

على الرغم من ذلك ، يبدو أن حجة C تعمل كما هو متوقع ، لذلك يمكن تنفيذها إذا أراد الناس استخدامها في الاستيفاء. ما زلت أرغب في طريقة = "كلاسيكية" أو استيفاء = "لا شيء" من شأنها أن تعمل مثل ويكيبيديا.

من أجل تصحيح الأخطاء ، هذا هو تطبيقي القبيح غير المقيد للطريقة الكلاسيكية:

def percentile (arr, p):
    arr = sorted(arr)

    index = p /100 * len(arr)

    # If index is a whole number, and larger than zero, subtract one unit (due to 0-based indexing)
    if index%1 < 0.0001 and index//1 > 0:
        index -= 1

    return arr[int(index)]

وأكثر من ذلك:

def indexes_classic(percentiles, set_size):
    percentiles = np.asarray(percentiles)

    indexes = percentiles / 100* set_size
    indexes[np.isclose(indexes%1, 0)] -= 1
    indexes = np.asarray(indexes, dtype=np.int)
    indexes[indexes < 0] = 0
    indexes[indexes > 100] = 100

    return indexes

تبدو هذه الاختلافات مثل مسائل الفاصلة العائمة / التقريب (التي أنت
يبدو على علم) ، وربما تخميني مع C = 0 كان خاطئًا وأنت تريد
ج = 0.5.
كانت وجهة نظري هي تحديد مصدر الاختلاف ("المعلمة C"
IMO ، على الرغم من وجود أسباب وجيهة لكراهية الكثيرين
مجموعات). لم يكن من أجل منحك / تنفيذ حل بديل.

أما بالنسبة للطريقة "الكلاسيكية" ، فأنا بصراحة لا أهتم كثيرًا بما هو كلاسيكي
من المفترض أن يكون. لكل ما أعرفه الكلاسيكية تعني "عدد غير قليل
يستخدمه الناس ".

الحل الحكيم ، انطباعي الأول هو أن "الكلاسيكية" أو أيا كان
name ، يضيف فقط خيارًا محيرًا آخر باسم غير واضح. آمل
أن هذه المناقشة يمكن أن تسير في اتجاه صنع كل شيء في الواقع
خيارات جيدة (شائعة) متاحة للمستخدمين بطريقة نظيفة وشفافة
الطريق. أفضل بطريقة قد يفهمها الناس بالفعل.

يمكننا إضافة طريقة أخرى ، لكن بصراحة أحبها نصفها فقط. عندما كنا
آخر إضافة المزيد من الأساليب (لا أتذكر ما تغير بالضبط)
تأخرت بالفعل وتمنى أن يقفز شخص ما ويكتشف
ما يجب أن يكون لدينا. وغني عن القول أن هذا لم يحدث أبدًا. و الأن
أحاول الإشارة إلى الاختلافات ومحاولة معرفة مدى ملاءمتها
مع ما لدينا حاليا.

لذلك ، انطباعي هو (مع وجود مشاكل محتملة مع التقريب والدقيق
المطابقات المئوية) لدينا (ربما أكثر من اللازم) العديد من خيارات "الإقحام"
وسيتطلب "معلمة C" أو أيًا كان ما تريد الاتصال به
تكون قادرة على فعل أي شيء تقريبًا.
وسأكون سعيدًا حقًا إذا أخبرني أحدهم كيف كل
(عام) "الطرق" الموجودة هناك تندرج في تلك الفئات ، على ما يبدو
أكثر من C = 0،0.5،1 موجودة حتى ، وربما بعضها خارجها
خيارات....

ربما أسير في الممر الخطأ ، لكن أضيف "Method1" بعلامة
اسم غير واضح لا يخبر أي شخص حقًا كيف يختلف عن
الأساليب الأخرى لا تبدو مفيدة لي (باستثناء شخص
يحدث أن تعرف بالفعل اسم "Method1" ويبحثون عنها. و
من فضلك لا تقل أن "الكلاسيكية" هي واحدة واضحة ، هناك
الكثير من التباين في عمليات التنفيذ هناك.

قد تكون هناك طريقة أخرى لإيقاف "الاستيفاء" ، ولكن مع وجود قائمة
من الطرق أيضًا أقل جمالًا بكثير ثم التلميح إلى "الاستيفاء الخطي"
للقول إنه ليس سلوكًا متدرجًا ، وما إلى ذلك .... وإذا ذهبنا بهذه الطريقة ،
ما زلت أريد نظرة عامة معقولة.

لا يتعين عليك القيام بذلك ، ولكن إذا أردنا إضافة طريقة جديدة ، فنحن بحاجة إلى ملف
طريقة إضافته التي لا تربك الجميع أكثر وهي واضحة!

اسمحوا لي أن ألخصها بعد ذلك:

1) في الوقت الحالي ، يقدم numpy طريقة واحدة مفيدة فقط: الاستيفاء = "الخطي" ، والآخرون مجرد اختلافات صغيرة حوله لا يبدو أنه يستخدمها أي شخص. الحزم الأخرى لديها العديد من الخيارات ذات الصلة.

2) إضافة القيم الأخرى لـ C = 0 أو C = 0.5 ، أمر منطقي بالنسبة لي. يمكن أن تعمل جميع طرق الاستيفاء جنبًا إلى جنب معها ، على الرغم من أنه لن يتم استخدامها أبدًا مرة أخرى.

3) إذا تمكنت إحدى المجموعات بين طرق الاستيفاء وحجة C ، من تكرار الطريقة الكلاسيكية (توافق المرجع وويكيبيديا وتجربتي الشخصية على أنها الطريقة الأكثر شيوعًا في التدريس) ، فأنا سعيد بها. يمكن أن يذكر في المستندات أن مثل هذا التحرير والسرد ينتج طريقة عدم الاستيفاء الكلاسيكية. لست متأكدًا مما إذا كان ذلك بسبب مشكلات تتعلق بدقة التعويم فقط ، لكنني أقدر جهودك لمعالجتها بطريقة أكثر تكاملاً!

4) إذا لم تحقق أي من المجموعات نفس النتيجة ، فأعتقد أن طريقة مختلفة ستكون منطقية. ربما يسمى الاستيفاء = "لا شيء" سيكون أقل إرباكًا.

باختصار: تبدو الخيارات الحالية لـ numpy.percentile مربكة ومحدودة إلى حد ما. تقدم الورقة المذكورة أعلاه نظرة عامة جيدة على الطرق المفيدة الأخرى. جنبًا إلى جنب مع صفحة ويكيبيديا ، يمكن أن يعملوا كنقطة انطلاق لتصميم مجموعة أكثر شمولاً ومفيدة من الخيارات لـ numpy.percentile. نأمل أن يرغب شخص ما في العمل على هذه المهمة.

هل "الأقرب" الحالي له معنى في بعض / أي حالات؟ إذا كانت طريقة التباعد ("C") أو أي شيء يحدث فرقًا كبيرًا في الاستيفاء الخطي / العناصر الكسرية ، فربما أتفاجأ من عدم قيام أحد بذلك من أجل التقريب غير الكسري ؟! هل كل هذا الدعم المستمر مهم ، وهل هناك سبب للتخلي عن الوسيطة العكسية CDF لطرق الاستيفاء؟

المجموعات غير مجدية ما لم تكن مفهومة ويسهل العثور عليها شائعة الاستخدام ، لذلك أشك في ذلك. بالنسبة إلى الاستيفاء ، يبدو أن العديد من الخيارات موجودة (على سبيل المثال http://mathworld.wolfram.com/Quantile.html Q4 إلى Q9 ، أعتقد أن توثيق R متطابق عمليًا ، لكنني أعتقد أنه من المحتمل ألا يكتمل ، على سبيل المثال matlab ...) ليس لدي أدنى فكرة عما إذا كانت جميعها منطقية ؛).

الشيء هو "الاستيفاء" يشير إلى ما يجب القيام به بين نقاط محددة تمامًا ، ولكن هناك العديد من الطرق (وغريبًا) لوضع تلك النقاط على الأقل عند استخدام "الاستيفاء الخطي" ، لذلك يبدو أنه أسلوب سيئ للإضافة إليه. لقد أردت "أقرب رتبة" تبدو كثيرًا (وهي في الروح) الاستيفاء = "الأقرب" ، لكن اختيار "موضع التآمر" الدقيق يبدو "غير قياسي" ، لذلك سيكون من المستحيل التخمين وبالتالي اختيار سيء.

ثم أفضل حتى إهمال كل شيء بعنف (ربما باستثناء الخطي).

ولكن ، إذا قللنا من قيمته ، فأنا أرغب في الحصول عليه بشكل صحيح بنسبة 100٪ ، وقد يحتاج ذلك إلى مزيد من الوضوح فيما يتعلق بما هو موجود وما يجب أن يوجد وما يجب ألا يكون موجودًا بالتأكيد.

أنا أتفق معك تماما

@ ricardoV94 : هل لديك أي آراء حول تعريفات linear للحالة الكمية الموزونة المقترحة في # 9211؟ توجد بعض الرسوم البيانية هناك بنفس الأسلوب.

ربما يستطيع @ ricardoV94 التعليق عليه (سيكون هذا رائعًا) ، لكنني أعتقد أن المشكلة متعامدة جدًا. من المحتمل أن تكون الأوزان مجرد أوزان من نوع التردد ، بافتراض عدم وجود أوزان أخرى محددة بشكل معقول للمئين (لا أرى كيف) ، فلا ينبغي أن يكون هناك أي غموض عند تنفيذها ، لكنني لا أعرف على وجه اليقين.

يمكنك أيضًا محاولة ping josef-pkt على تلك العلاقات العامة وتأمل أن يكون لديه تعليق سريع سواء كان يعتقد أنها فكرة جيدة / صحيحة.

إذا أراد أي شخص أخذها من هنا ، فقد كتبت دالة غير محسّنة تحسب ملف
9 طرق تقدير النسبة المئوية / الكمية التي وصفها Hyndman and Fan (1996) وتستخدم أيضًا في R.

الطريقة 1 تتوافق مع "طريقة الترتيب الأقرب الكلاسيكية" كما تمت مناقشتها في ويكيبيديا . الطريقة 7 مكافئة لتطبيق Numpy الحالي (الاستيفاء = "الخطي"). لم يتم تضمين الطرق المتبقية لاستيفاء Numpy (ولا يبدو أنها مفيدة على أي حال).

def percentile(x, p, method=7):
    '''
    Compute the qth percentile of the data.

    Returns the qth percentile(s) of the array elements.

    Parameters
    ----------
    x : array_like
        Input array or object that can be converted to an array.
    p : float in range of [0,100] (or sequence of floats)
        Percentile to compute, which must be between 0 and 100 inclusive.
    method : integer in range of [1,9]
        This optional parameter specifies one of the nine sampling methods 
        discussed in Hyndman and Fan (1996). 

        Methods 1 to 3 are discontinuous:
        * Method 1: Inverse of empirical distribution function (oldest
        and most studied method).
        * Method 2: Similar to type 1 but with averaging at discontinuities.
        * Method 3: SAS definition: nearest even order statistic.

        Methods 4 to 9 are continuous and equivalent to a linear interpolation 
        between the points (pk,xk) where xk is the kth order statistic. 
        Specific expressions for pk are given below:
        * Method 4: pk=kn. Linear interpolation of the empirical cdf.
        * Method 5: pk=(k−0.5)/n. Piecewise linear function where the knots 
        are the values midway through the steps of the empirical cdf 
        (Popular amongst hydrologists, used by Mathematica?).
        * Method 6: pk=k/(n+1), thus pk=E[F(xk)]. The sample space is divided
        in n+1 regions, each with probability of 1/(n+1) on average
        (Used by Minitab and SPSS).
        * Method 7: pk=(k−1)/(n−1), thus pk=mode[F(xk)]. The sample space
        is divided into n-1 regions (This is the default method of 
        Numpy, R, S, and MS Excell).
        * Method 8: pk=(k−1/3)/(n+1/3), thus pk≈median[F(xk)]. The resulting
        estimates are approximately median-unbiased regardless of the
        distribution of x (Recommended by Hyndman and Fan (1996)).
        * Method 9: k=(k−3/8)/(n+1/4), thus pk≈F[E(xk)]if x is normal (?).
        The resulting estimates are approximately unbiased for the expected 
        order statistics if x is normally distributed (Used for normal QQ plots).

        References:
        Hyndman, R. J. and Fan, Y. (1996) Sample quantiles in statistical packages, 
        American Statistician 50, 361--365.
        Schoonjans, F., De Bacquer, D., & Schmid, P. (2011). Estimation of population
        percentiles. Epidemiology (Cambridge, Mass.), 22(5), 750.

        '''

    method = method-1    
    x = np.asarray(x)
    x.sort()
    p = np.array(p)/100

    n = x.size  
    m = [0, 0, -0.5, 0, 0.5, p, 1-p, (p+1)/3, p/4+3/8][method]

    npm = n*p+m
    j = np.floor(npm).astype(np.int)
    g = npm-j

    # Discontinuous functions
    if method < 3:
        yg0 = [0, 0.5, 0][method]
        y = np.ones(p.size)
        if method < 2:
            y[g==0] = yg0
        else:
            y[(g==0) & (j%2 == 0)] = yg0      
    # Continuous functions
    else:
        y = g

    # Adjust indexes to work with Python
    j_ = j.copy()
    j[j<=0] = 1
    j[j > n] = n
    j_[j_ < 0] = 0
    j_[j_ >= n] = n-1 

    return (1-y)* x[j-1] + y*x[j_]

يمكن أيضًا تنفيذ الطرق المستمرة بشكل أكثر كفاءة مثل هذا.

def percentile_continuous(x, p, method=7):
    '''
    Compute the qth percentile of the data.

    Returns the qth percentile(s) of the array elements.

    Parameters
    ----------
    x : array_like
        Input array or object that can be converted to an array.
    p : float in range of [0,100] (or sequence of floats)
        Percentile to compute, which must be between 0 and 100 inclusive.
    method : integer in range of [4,9]
        This optional parameter specifies one of the 5 continuous sampling
        methods discussed in Hyndman and Fan (1996). 
        '''

    x = np.asarray(x)
    x.sort()
    p = np.asarray(p)/100
    n = x.size

    if method == 4:
        r = p * n
    elif method == 5:
        r = p * n + .5
    elif method == 6:
        r = p * (n+1)
    elif method == 7:
        r = p * (n-1) + 1
    elif method == 8:
        r = p * (n+1/3) + 1/3
    elif method == 9:
        r = p * (n+1/4) + 3/8

    index = np.floor(r).astype(np.int)

    # Adjust indexes to work with Python
    index_ = index.copy()
    index[index_ <= 0] = 1
    index[index_  > n] = n
    index_[index_ < 0] = 0
    index_[index_ >= n] = n-1

    i = x[index - 1]
    j = x[index_]

    return i + r%1* (j-i)

أي شخص يريد أن يأخذها من هنا؟ أنا لست مؤهلا للقيام بذلك.

كما هو مذكور في المنشور السابق ، يبدو أن التنفيذ الافتراضي الحالي لـ Numpy للكمية يطابق ذلك في R .

في R :

> quantile(c(15, 20, 35, 40, 50), probs=c(0.05, 0.3, 0.4, 0.5, 1))
  5%  30%  40%  50% 100% 
  16   23   29   35   50 
> quantile(c(3, 6, 7, 8, 8, 10, 13, 15, 16, 20), probs=c(0.25, 0.5, 0.75, 1))
  25%   50%   75%  100% 
 7.25  9.00 14.50 20.00
> quantile(c(3, 6, 7, 8, 8, 9, 10, 13, 15, 16, 20), probs=c(0.25, 0.5, 0.75, 1))
 25%  50%  75% 100% 
 7.5  9.0 14.0 20.0 

في np.quantile :

>>> np.quantile([15, 20, 35, 40, 50], q=[0.05, 0.3, 0.4, 0.5, 1])
array([16., 23., 29., 35., 50.])
>>> np.quantile([3, 6, 7, 8, 8, 10, 13, 15, 16, 20], q=[0.25, 0.5, 0.75, 1])
array([ 7.25,  9.  , 14.5 , 20.  ])
>>> np.quantile([3, 6, 7, 8, 8, 9, 10, 13, 15, 16, 20], q=[0.25, 0.5, 0.75, 1])
array([ 7.5,  9. , 14. , 20. ])

والتي بالطبع لا تعيد إنتاج الأمثلة الواردة في ويكيبيديا:
https://en.wikipedia.org/wiki/Percentile

في الواقع ، إذا انتقلت إلى صفحة المساعدة R للحصول على https://www.rdocumentation.org/packages/stats/versions/3.5.0/topics/quantile
ستلاحظ أن الطريقة الافتراضية R (النوع 7) تحدد شروط الحدود المماثلة لكيفية تعيينها np.quantile : p_k = (k-1) / (n-1) ، حيث n هو حجم العينة ، و k = 1 تشير إلى الأصغر القيمة ، بينما k = n الأكبر. هذا يعني أن أصغر قيمة في المصفوفة التي تم فرزها مثبتة عند مقدر = 0 ، وأكبر قيمة مثبتة بالكمية = 1.

كما هو مذكور في المنشور السابق ، يمكنك إعادة إنتاج 3 أمثلة في ويكيبيديا بالنوع 1:

> quantile(c(15, 20, 35, 40, 50), probs=c(0.05, 0.3, 0.4, 0.5, 1), type=1)
  5%  30%  40%  50% 100% 
  15   20   20   35   50 
> quantile(c(3, 6, 7, 8, 8, 10, 13, 15, 16, 20), probs=c(0.25, 0.5, 0.75, 1), type=1)
 25%  50%  75% 100% 
   7    8   15   20 
> quantile(c(3, 6, 7, 8, 8, 9, 10, 13, 15, 16, 20), probs=c(0.25, 0.5, 0.75, 1), type=1)
 25%  50%  75% 100% 
   7    9   15   20 

هذا يثير بعض الأسئلة المثيرة للاهتمام:

1.) هل يجب أن يتتبع np.quantile الافتراضي القيمة الافتراضية لـ R.quantile؟
2.) هل يجب تحويل np.quantile إلى خوارزمية النوع 1؟

بما أن ويكيبيديا نفسها توافق على أنه لا يوجد تعريف موحد للنسب المئوية ، أعتقد أنه طالما أن الخوارزمية سليمة والمستخدم على دراية بكيفية عملها ، فلا (1) أو (2) مهمان كثيرًا. أنا أؤيد (1) لأن Python و R هما من أكثر منصات تحليل البيانات شيوعًا ، وسيكون من الجيد إذا كان بإمكانهما فحص بعضهما البعض. بالنظر إلى ذلك ، أعتقد أن (2) غير ضروري.

نعم ، كل من R و Numpy افتراضيان للطريقة 7 ويجب الاحتفاظ بهما على هذا النحو. السؤال حول إضافة الطرق الأخرى أم لا.

إذا كان أي شخص مهتمًا ، فقد أعددت وحدة مستقلة باستخدام طرق النسبة المئوية 9 ، هنا . لا تتردد في استخدامه أو التكيف مع Numpy إذا كنت تعرف كيف.

شكرا لك @ ricardoV94 .

لذلك ، فقط للركلات ، قمت بإجراء استطلاع في العمل على مستخدمي R. من بين 20 شخصًا أجابوا ، استخدم 20 فقط الطريقة الافتراضية في quantile . وهي تتراوح من طلاب الماجستير في الصحة العامة إلى باحثي الدكتوراه في الإحصاء.

أنا شخصياً لست متأكدًا مما إذا كان الأمر يستحق مجهود numpy لدعم 9 طرق مختلفة لحساب الكم. أعتقد أن معظم المستخدمين سيستخدمون الإعداد الافتراضي فقط.

لما يستحق ، هناك دالة scipy.stats.mstats.mquantiles التي تدعم 6 من 9 طرق (المستمرة) ويذكر المستند بوضوح شديد الروابط مع تنفيذ R.

albertcthomas آه ، من الجيد معرفة ذلك. على الرغم من أنني أعتقد بشكل مثالي أننا سنخفي هذا التعقيد في قطعة صغيرة قليلاً. ونحتاج في الغالب إلى إصلاح الإصدارات غير المتجاورة IIRC. لأن هؤلاء في الأساس لا يقدمون الطرق الأكثر شيوعًا.

نعم بالفعل ، قد لا يضطر numpy بالضرورة إلى دعم هذه الأساليب إذا تم تنفيذها في وحدة scipy stats.

أنا شخصياً أؤيد وجود طريقة لحساب الكم من المعكوس العام لوظيفة التوزيع التراكمي. حقيقة أن مثل هذه الطريقة غير متوفرة تقودني إلى هذه المشكلة :).

albertcthomas إذا كان لديك أي تلميحات / معرفة حول هذا ، من فضلك قل ذلك! نحن عالقون بعض الشيء بسبب الافتقار إلى الوضوح ما هو التقصير الجيد في الواقع. وأعتقد أنها قضية مزعجة للغاية.

والأهم من ذلك أننا نحتاج إلى بعض الإعدادات الافتراضية الجيدة. وهذا يعني على الأرجح تنفيذ 2-3 طرق (تجديد كامل للطرق غير المتجاورة). أنا موافق على دعم المزيد أو أكثر من الأشياء المعقدة ، لكني أرغب إذا كان بإمكاننا اتخاذ قرار بشأن عدد قليل من الأشياء "النموذجية / الجيدة".

أود أن أقول إن الطريقة الخطية (الافتراضية الحالية) وعكس دالة التوزيع التراكمي (التي كنت أبحث عنها عندما أنشأت هذه المشكلة ، وكذلك albertcthomas إذا فهمت بشكل صحيح) ستكون كافية. في الأساس ، يسمح للشخص باختيار ما إذا كان يريد الاستيفاء أم لا.

ويجب إزالة البدائل الأخرى المطبقة حاليًا.

يجب بالتأكيد إضافة معكوس دالة التوزيع التراكمي. إنه أحد أكثر المقدرات شيوعًا للكمية من عينة معينة من الملاحظات في الإحصاء.

ويجب إزالة البدائل الأخرى المطبقة حاليًا.

@ ricardoV94 هل تقول هذا لأنه لم تتم الإشارة إلى أي من البدائل في ويكيبيديا ولا ورقة Hyndman and Fan؟

نعم ، أفيك لم يتم تنفيذها في أي حزمة أخرى.

لا أفهم سبب رغبة أي شخص في استخدام هذه الأساليب ، وأسمائهم كذلك
قد تكون مضللة أيضًا.

Albert Thomas [email protected] escreveu no dia quarta ، 2/01/2019
آ (ق) 14:18:

ويجب أن تكون البدائل الأخرى المطبقة حاليًا كذلك
إزالة.

@ ricardoV94 https://github.com/ricardoV94 هل تقول هذا بسبب
لم تتم الإشارة إلى أي من البدائل في ويكيبيديا ولا في Hyndman و
ورق المروحة؟

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/numpy/numpy/issues/10736#issuecomment-450861068 ، أو كتم الصوت
الخيط
https://github.com/notifications/unsubscribe-auth/AbpAmfUoJNk3YHOSHNeVN03Va5wtvkHQks5u_LGugaJpZM4SnVpE
.

شكر! لماذا لا تفتح العلاقات العامة لإضافة معكوس التوزيع التراكمي كطريقة متوفرة في np.percentile؟ مع الإبقاء على هذه المشكلة مفتوحة إذا أردنا الاستمرار في مناقشة البدائل (باستثناء الخيار الافتراضي الحالي الذي يجب أن يظل الافتراضي). كيف يتم التعامل مع الإهمال في numpy؟

بعض المعلومات الإضافية هنا - أضاف Python 3.8 statistics.quantiles - يجب أن ننظر في إضافة وضع مكافئ إلى np.quantile

ربما يكون الطريق إلى الأمام هنا هو إضافة method kwarg يعكس statistics واحد ، وإمكانية إضافة 0-2 أخرى (في هذه الحالة سيكون من الجيد اختبار اتصال المؤلفين الأصليين في python) .

لست متأكدًا مما إذا كانت الإعدادات الافتراضية تتطابق بيننا وبينهم ، وهو أمر سيكون عارًا إذا لم يفعلوا ذلك ، لكنها لا تزال تبدو أفضل فكرة (وإلى حد كبير ما كان يدور في خلدنا على أي حال). 0-2 "طرق" جديدة يمكن إضافتها أيضًا. في هذه الحالة ، سيكون من الجيد إجراء اختبار ping للأشخاص على إحصائيات بيثون على الأسماء الفعلية ...

مرحبًا بكم في العلاقات العامة ، أود أن أتحرك للأمام ، لكنني لن أفعل ذلك في المستقبل القريب.

@ eric-wieser ألاحظ أن لديك اثنين من العلاقات العامة ذات الصلة المعلقة ، هل يتعامل أي منهم مع هذا؟

سأقوم بدفع هذا إلى 1.19 لذا فهو ليس مانعًا. لكن هذا لا يعني أنه لا يمكن إصلاحه لـ 1.18 :)

charris : ما هي

لا أعتقد أن هناك أي شيء في هذا الاتجاه حتى الآن ، للأسف.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

Levstyle picture Levstyle  ·  3تعليقات

manuels picture manuels  ·  3تعليقات

inducer picture inducer  ·  3تعليقات

astrofrog picture astrofrog  ·  4تعليقات

keithbriggs picture keithbriggs  ·  3تعليقات