it-swarm.dev

Argsort numpy - ماذا تفعل؟

لماذا يعطي هذا نتيجة سيئة:

x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()

>[2 3 1 0]

عندما أتوقع أن تفعل هذا:

[3 2 0 1]

من الواضح أن فهمي للوظيفة غير موجود.

97
user1276273

حسب الوثائق

إرجاع المؤشرات التي من شأنها فرز مجموعة.

  • 2 هو فهرس 0.0.
  • 3 هو فهرس 0.1.
  • 1 هو فهرس 1.41.
  • 0 هو فهرس 1.48.
110
falsetru

يشير [2, 3, 1, 0] إلى أن أصغر عنصر في الفهرس 2 ، الأصغر التالي في الفهرس 3 ، ثم الفهرس 1 ، ثم الفهرس 0.

هناك عدة طرق للحصول على النتيجة التي تبحث عنها:

import numpy as np
import scipy.stats as stats

def using_indexed_assignment(x):
    "https://stackoverflow.com/a/5284703/190597 (Sven Marnach)"
    result = np.empty(len(x), dtype=int)
    temp = x.argsort()
    result[temp] = np.arange(len(x))
    return result

def using_rankdata(x):
    return stats.rankdata(x)-1

def using_argsort_twice(x):
    "https://stackoverflow.com/a/6266510/190597 (k.rooijers)"
    return np.argsort(np.argsort(x))

def using_digitize(x):
    unique_vals, index = np.unique(x, return_inverse=True)
    return np.digitize(x, bins=unique_vals) - 1

فمثلا،

In [72]: x = np.array([1.48,1.41,0.0,0.1])

In [73]: using_indexed_assignment(x)
Out[73]: array([3, 2, 0, 1])

يتحقق هذا من أنهم جميعًا ينتجون نفس النتيجة:

x = np.random.random(10**5)
expected = using_indexed_assignment(x)
for func in (using_argsort_twice, using_digitize, using_rankdata):
    assert np.allclose(expected, func(x))

تشير مقاييس IPython %timeit هذه إلى المصفوفات الكبيرة using_indexed_assignment الأسرع:

In [50]: x = np.random.random(10**5)
In [66]: %timeit using_indexed_assignment(x)
100 loops, best of 3: 9.32 ms per loop

In [70]: %timeit using_rankdata(x)
100 loops, best of 3: 10.6 ms per loop

In [56]: %timeit using_argsort_twice(x)
100 loops, best of 3: 16.2 ms per loop

In [59]: %timeit using_digitize(x)
10 loops, best of 3: 27 ms per loop

بالنسبة للصفائف الصغيرة ، قد يكون using_argsort_twice أسرع:

In [78]: x = np.random.random(10**2)

In [81]: %timeit using_argsort_twice(x)
100000 loops, best of 3: 3.45 µs per loop

In [79]: %timeit using_indexed_assignment(x)
100000 loops, best of 3: 4.78 µs per loop

In [80]: %timeit using_rankdata(x)
100000 loops, best of 3: 19 µs per loop

In [82]: %timeit using_digitize(x)
10000 loops, best of 3: 26.2 µs per loop

لاحظ أيضًا أن stats.rankdata يمنحك المزيد من التحكم في كيفية التعامل مع العناصر ذات القيمة المتساوية.

32
unutbu

كما الوثائق يقول ، argsort:

إرجاع المؤشرات التي من شأنها فرز مجموعة.

هذا يعني أن العنصر الأول في argsort هو فهرس العنصر الذي يجب فرزه أولاً ، والعنصر الثاني هو فهرس العنصر الذي يجب أن يكون الثاني ، إلخ.

ما يبدو أنك تريده هو ترتيب ترتيب القيم ، وهو ما يتم توفيره بواسطة scipy.stats.rankdata . لاحظ أنك بحاجة إلى التفكير فيما يجب أن يحدث إذا كانت هناك روابط في الرتب.

2
BrenBarn

تُرجع np.argsort فهرس الصفيف المصنف المعطى بواسطة "النوع" (الذي يحدد نوع خوارزمية الفرز). ومع ذلك ، عند استخدام قائمة مع np.argmax ، فإنها تُرجع فهرس العنصر الأكبر في القائمة. بينما ، np.sort ، يفرز الصفيف المحدد ، القائمة.

0
vivek

فقط أريد أن أقارن مباشرة فهم OP الأصلي مع التنفيذ الفعلي مع الكود.

يتم تعريف numpy.argsort بحيث

x[x.argsort()] == numpy.sort(x) # this will be an array of True's

اعتقد البروتوكول الاختياري في الأصل أنه تم تعريفه على هذا النحو

x == numpy.sort(x)[x.argsort()] # this will not be True
0
Multihunter

إدخال:
استيراد numpy كـ np
x = np.array ([1.48،1.41،0.0،0.1])
x.argsort (). argsort ()

انتاج:
صفيف ([3 ، 2 ، 0 ، 1])

0
JMpony

numpy.argsort (a ، المحور = -1 ، kind = 'quicksort' ، الترتيب = بلا)

إرجاع المؤشرات التي من شأنها فرز مجموعة

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

النظر في مثال واحد في بيثون ، وجود قائمة من القيم كما

listExample  = [0 , 2, 2456,  2000, 5000, 0, 1]

الآن نستخدم وظيفة argsort:

import numpy as np
list(np.argsort(listExample))

سوف يكون الإخراج

[0, 5, 6, 1, 3, 2, 4]

هذه هي قائمة مؤشرات القيم في listExample إذا قمت بتعيين هذه المؤشرات على القيم المعنية ، فسنحصل على النتيجة كما يلي:

[0, 0, 1, 2, 2000, 2456, 5000]

(أجد هذه الوظيفة مفيدة للغاية في العديد من الأماكن على سبيل المثال ، إذا كنت ترغب في فرز القائمة/الصفيف ولكن لا تريد استخدام list.sort () وظيفة (أي دون تغيير ترتيب القيم الفعلية في القائمة) ، يمكنك استخدام هذا وظيفة.)

لمزيد من التفاصيل ، يرجى الرجوع إلى هذا الرابط: https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.argsort.html

0
Yogesh

أولاً ، تم طلب الصفيف. ثم قم بإنشاء صفيف باستخدام الفهرس الأولي للصفيف.

0
Rodrigo Saraguro