Numpy: argsort๊ฐ€ ์ž˜๋ชป๋œ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2017๋…„ 03์›” 08์ผ  ยท  4์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: numpy/numpy

argsort ๊ธฐ๋Šฅ์ด ์†์ƒ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ œ๊ณต๋œ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ํ–‰ [0, 1]์— ๋Œ€ํ•œ argsort๋Š” ์ •ํ™•ํ•˜์ง€๋งŒ ํ–‰ [2, 3]์— ๋Œ€ํ•ด์„œ๋Š” ์—‰๋ง์ž…๋‹ˆ๋‹ค.
๋‹ค๋ฅธ NumPy ์„ค์น˜ ๋ฐ ๋ฒ„์ „ 1.11.0 ๋ฐ 1.12.0์—์„œ ์ด๊ฒƒ์„ ํ…Œ์ŠคํŠธํ–ˆ์Šต๋‹ˆ๋‹ค.

import numpy as np

vec = np.array([
    [-1.4, -1.2,  1.3],
    [-3.6,  3.9, -3.7],
    [-2.3,  1.5, -2. ],
    [-2.6,  2.4, -1.6]
    ])

In [1]: np.argsort(-vec, axis=1)
Out[1]: 
array([[2, 1, 0],
       [1, 0, 2],
       [1, 2, 0],
       [1, 2, 0]])
53 - Invalid

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์ด๊ฒƒ์€ "np argsort wrong"์— ๋Œ€ํ•œ ๋‘ ๋ฒˆ์งธ Google ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค.

๋ฌธ์„œ ํŽ˜์ด์ง€์˜ ์„ค๋ช…์ด (๋‚˜์—๊ฒŒ) ๋ช…ํ™•ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ ๋„์›€์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ผ๋ฉฐ ์—ฌ๊ธฐ์— ์ œ ์„ค๋ช…์„ ์ถ”๊ฐ€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

x = numpy.array([1.48,1.31,0.0,0.8])
print x.argsort()

>[2 3 1 0]

์–ด๋–ค ์‚ฌ๋žŒ๋“ค์€ ์ด๊ฒƒ์ด ๋Œ€์‹  [3, 2, 0, 1] ๋ฅผ ์ค„ ๊ฒƒ์ด๋ผ๊ณ  ์˜ˆ์ƒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์ •๋ ฌ๋˜์ง€ ์•Š์€ ๋ฐฐ์—ด์˜ 0๋ฒˆ์งธ ์š”์†Œ๋Š” ์ •๋ ฌ๋œ ๋ฐฐ์—ด์˜ 3๋ฒˆ์งธ ์š”์†Œ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ ํ•˜๋Š” ์ผ์€ x[np.argsort(x)] ๊ฐ€ ์ •๋ ฌ๋œ ๋ชฉ๋ก, ์ฆ‰ [0.0, 0.8, 1.31, 1.48] ๋ฅผ ์ œ๊ณตํ•˜๋„๋ก ์ธ๋ฑ์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค์‹œ ๋งํ•ด [2 3 1 0] ๋Š” ์ •๋ ฌ๋œ ๋ฐฐ์—ด์˜ 0๋ฒˆ์งธ ์š”์†Œ๊ฐ€ ์ •๋ ฌ๋˜์ง€ ์•Š์€ ๋ฐฐ์—ด์˜ 2๋ฒˆ์งธ ์š”์†Œ์ž„์„ ์•Œ๋ ค์ค๋‹ˆ๋‹ค.

[3, 2, 0, 1] ๋ฅผ ์ถœ๋ ฅ์œผ๋กœ ์–ป์œผ๋ ค๋ฉด ๋Œ€์‹  ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

np.argsort(np.argsort(x))
>[3 2 0 1]

๋˜๋Š” x ์—์„œ ๊ฐ€์žฅ ํฐ 3๊ฐœ ์š”์†Œ์˜ ์ธ๋ฑ์Šค๋งŒ ์›ํ•˜๋Š” ๊ฒฝ์šฐ:

np.argsort(x)[:-4:-1]
>[0, 1, 3]

๋ชจ๋“  4 ๋Œ“๊ธ€

๊ฒฐ๊ณผ์— ๋ฌธ์ œ๊ฐ€ ์—†๋Š”์ง€ ํ™•์ธํ•˜๊ณ  vec[np.arange(4)[:, np.newaxis], np.argsort(-vec, axis=1)] ๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  ์ž˜ ๋ณด์ด๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

์ด๊ฒƒ์€ "np argsort wrong"์— ๋Œ€ํ•œ ๋‘ ๋ฒˆ์งธ Google ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค.

๋ฌธ์„œ ํŽ˜์ด์ง€์˜ ์„ค๋ช…์ด (๋‚˜์—๊ฒŒ) ๋ช…ํ™•ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ ๋„์›€์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ผ๋ฉฐ ์—ฌ๊ธฐ์— ์ œ ์„ค๋ช…์„ ์ถ”๊ฐ€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

x = numpy.array([1.48,1.31,0.0,0.8])
print x.argsort()

>[2 3 1 0]

์–ด๋–ค ์‚ฌ๋žŒ๋“ค์€ ์ด๊ฒƒ์ด ๋Œ€์‹  [3, 2, 0, 1] ๋ฅผ ์ค„ ๊ฒƒ์ด๋ผ๊ณ  ์˜ˆ์ƒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์ •๋ ฌ๋˜์ง€ ์•Š์€ ๋ฐฐ์—ด์˜ 0๋ฒˆ์งธ ์š”์†Œ๋Š” ์ •๋ ฌ๋œ ๋ฐฐ์—ด์˜ 3๋ฒˆ์งธ ์š”์†Œ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ ํ•˜๋Š” ์ผ์€ x[np.argsort(x)] ๊ฐ€ ์ •๋ ฌ๋œ ๋ชฉ๋ก, ์ฆ‰ [0.0, 0.8, 1.31, 1.48] ๋ฅผ ์ œ๊ณตํ•˜๋„๋ก ์ธ๋ฑ์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค์‹œ ๋งํ•ด [2 3 1 0] ๋Š” ์ •๋ ฌ๋œ ๋ฐฐ์—ด์˜ 0๋ฒˆ์งธ ์š”์†Œ๊ฐ€ ์ •๋ ฌ๋˜์ง€ ์•Š์€ ๋ฐฐ์—ด์˜ 2๋ฒˆ์งธ ์š”์†Œ์ž„์„ ์•Œ๋ ค์ค๋‹ˆ๋‹ค.

[3, 2, 0, 1] ๋ฅผ ์ถœ๋ ฅ์œผ๋กœ ์–ป์œผ๋ ค๋ฉด ๋Œ€์‹  ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

np.argsort(np.argsort(x))
>[3 2 0 1]

๋˜๋Š” x ์—์„œ ๊ฐ€์žฅ ํฐ 3๊ฐœ ์š”์†Œ์˜ ์ธ๋ฑ์Šค๋งŒ ์›ํ•˜๋Š” ๊ฒฝ์šฐ:

np.argsort(x)[:-4:-1]
>[0, 1, 3]

์‹ค์ œ๋กœ [3, 2, 0, 1]์„ ์ถœ๋ ฅ์œผ๋กœ ์–ป์œผ๋ ค๋ฉด ๋Œ€์‹  ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋” ๋น ๋ฆ…๋‹ˆ๋‹ค.

a = np.empty(len(x), np.intp)
a[np.argsort(x)] = np.arange(len(x))

9880์€ ์ด๊ฒƒ์„ numpy์— np.invert_permutation(np.argsort(x)) ๋กœ ์ถ”๊ฐ€ํ•  ๊ฒƒ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค.

@rossbar , @bjnath : ์œ„์˜ @ghost ์˜ ์ฝ”๋ฉ˜ํŠธ์—์„œ ๋ฌด์–ธ๊ฐ€๋ฅผ ์ถ”์ถœํ•˜์—ฌ ๋ฌธ์„œ์— ๋„ฃ์„ ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ํ˜ผ๋ž€์˜ ๋” ๋งŽ์€ ์˜ˆ๋ฅผ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ๋” ๋งŽ์€ ๊ต์ฐจ ๋งํฌ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰