ทำไม numpy จึงให้ผลลัพธ์นี้:
x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()
>[2 3 1 0]
เมื่อฉันคาดหวังว่าจะทำสิ่งนี้:
[3 2 0 1]
เห็นได้ชัดว่าฉันขาดความเข้าใจเกี่ยวกับฟังก์ชันนี้
ทำไม numpy จึงให้ผลลัพธ์นี้:
x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()
>[2 3 1 0]
เมื่อฉันคาดหวังว่าจะทำสิ่งนี้:
[3 2 0 1]
เห็นได้ชัดว่าฉันขาดความเข้าใจเกี่ยวกับฟังก์ชันนี้
คำตอบ:
ตามเอกสารประกอบ
ส่งคืนดัชนีที่จะจัดเรียงอาร์เรย์
2
0.0
เป็นดัชนีของ3
0.1
เป็นดัชนีของ1
1.41
เป็นดัชนีของ0
1.48
เป็นดัชนีของa = x.argsort()
พิมพ์x[a]
เราจะได้รับarray([ 0. , 0.1 , 1.41, 1.48])
[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))
%timeit
เกณฑ์มาตรฐานIPython เหล่านี้แนะนำสำหรับอาร์เรย์ขนาดใหญ่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
ช่วยให้คุณควบคุมวิธีจัดการองค์ประกอบที่มีมูลค่าเท่ากันได้มากขึ้น
argsort
ส่งคืนดัชนีของอาร์เรย์ที่เรียงลำดับ ดัชนีของดัชนีที่เรียงลำดับคืออันดับ นี่คือสิ่งที่เรียกร้องให้argsort
กลับมาครั้งที่สอง
ตามเอกสารระบุว่าargsort
:
ส่งคืนดัชนีที่จะจัดเรียงอาร์เรย์
นั่นหมายความว่าองค์ประกอบแรกของ argsort คือดัชนีขององค์ประกอบที่ควรเรียงลำดับก่อนองค์ประกอบที่สองคือดัชนีขององค์ประกอบที่ควรเป็นอันดับสองเป็นต้น
scipy.stats.rankdata
สิ่งที่คุณดูเหมือนจะต้องการเป็นลำดับของค่าซึ่งเป็นสิ่งที่ให้บริการโดย โปรดทราบว่าคุณต้องคิดถึงสิ่งที่จะเกิดขึ้นหากมีความสัมพันธ์ในอันดับ
numpy.argsort (a, axis = -1, kind = 'quicksort', order = None)
ส่งคืนดัชนีที่จะจัดเรียงอาร์เรย์
ดำเนินการจัดเรียงทางอ้อมตามแกนที่กำหนดโดยใช้อัลกอริทึมที่ระบุโดยคีย์เวิร์ดชนิด ส่งคืนอาร์เรย์ของดัชนีที่มีรูปร่างเดียวกันกับข้อมูลดัชนีตามแกนที่กำหนดตามลำดับที่จัดเรียง
พิจารณาตัวอย่างหนึ่งใน python ซึ่งมีรายการค่าเป็น
listExample = [0 , 2, 2456, 2000, 5000, 0, 1]
ตอนนี้เราใช้ฟังก์ชัน argsort:
import numpy as np
list(np.argsort(listExample))
ผลลัพธ์จะเป็น
[0, 5, 6, 1, 3, 2, 4]
นี่คือรายการดัชนีของค่าใน listExam ตัวอย่างหากคุณจับคู่ดัชนีเหล่านี้กับค่าตามลำดับเราจะได้ผลลัพธ์ดังนี้:
[0, 0, 1, 2, 2000, 2456, 5000]
(ฉันพบว่าฟังก์ชันนี้มีประโยชน์มากในหลาย ๆ ที่เช่นหากคุณต้องการจัดเรียงรายการ / อาร์เรย์ แต่ไม่ต้องการใช้ฟังก์ชัน list.sort () (เช่นโดยไม่ต้องเปลี่ยนลำดับของค่าจริงในรายการ) คุณสามารถใช้สิ่งนี้ได้ ฟังก์ชั่น.)
สำหรับรายละเอียดเพิ่มเติมโปรดดูที่ลิงค์นี้: https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.argsort.html
อินพุต:
นำเข้า numpy เป็น np
x = np.array ([1.48,1.41,0.0,0.1])
x.argsort (). argsort ()
เอาต์พุต:
อาร์เรย์ ([3, 2, 0, 1])
ขั้นแรกมันถูกสั่งให้อาร์เรย์ จากนั้นสร้างอาร์เรย์ด้วยดัชนีเริ่มต้นของอาร์เรย์
np.argsort ส่งคืนดัชนีของอาร์เรย์ที่เรียงลำดับตาม 'ชนิด' (ซึ่งระบุประเภทของอัลกอริทึมการเรียงลำดับ) อย่างไรก็ตามเมื่อรายการถูกใช้กับ np.argmax จะส่งกลับดัชนีขององค์ประกอบที่ใหญ่ที่สุดในรายการ ในขณะที่ np.sort จัดเรียงอาร์เรย์ที่กำหนดรายการ
เพียงแค่ต้องการเปรียบเทียบความเข้าใจดั้งเดิมของ OP โดยตรงกับการใช้งานจริงด้วยโค้ด
numpy.argsort
ถูกกำหนดไว้สำหรับอาร์เรย์ 1D:
x[x.argsort()] == numpy.sort(x) # this will be an array of True's
เดิมที OP คิดว่ามันถูกกำหนดไว้สำหรับอาร์เรย์ 1D:
x == numpy.sort(x)[x.argsort()] # this will not be True
หมายเหตุ:รหัสนี้ใช้ไม่ได้ในกรณีทั่วไป (ใช้ได้กับ 1D เท่านั้น) คำตอบนี้ใช้เพื่อจุดประสงค์ในการอธิบายเท่านั้น
x[x.argsort()]
np.sort(x)
ไม่จำเป็นต้องเป็นเช่นเดียวกับ จริงๆแล้วมันไม่จำเป็นต้องมีรูปร่างเหมือนกันด้วยซ้ำ ลองใช้อาร์เรย์ 2D สิ่งนี้เกิดขึ้นกับอาร์เรย์ 1D เท่านั้น
มันส่งคืนดัชนีตามดัชนีอาร์เรย์ที่กำหนด[1.48,1.41,0.0,0.1]
นั่นหมายถึง:
0.0
เป็นองค์ประกอบแรกในดัชนี [2]
0.1
เป็นองค์ประกอบที่สองในดัชนี [3]
1.41
เป็นองค์ประกอบที่สามในดัชนี [1]
1.48
เป็นองค์ประกอบที่สี่ในดัชนี [0] เอาท์พุท:
[2,3,1,0]
[3 2 0 1]
เป็นคำตอบที่ถูกต้อง