_2010-06-18 trac ์ฌ์ฉ์ rspringuel์ ์๋ณธ ํฐ์ผ http://projects.scipy.org/numpy/ticket/1514 , unknown์ ํ ๋น ๋จ _
์ฌ๋ฌ NaN ํญ๋ชฉ์ด์๋ ๋ฐฐ์ด์์ unique๊ฐ ์๋ํ๋ฉด ์๋ ๋ฐฐ์ด์์ NaN์ด์๋ ๊ฐ ํญ๋ชฉ์ ๋ํ NaN์ด ๋ฐํ๋ฉ๋๋ค.
์ :
a = random.randint (5, size = 100) .astype (float)
a [12] = nan # ๋จ์ผ nan ํญ๋ชฉ ์ถ๊ฐ
๊ณ ์ (a)
๋ฐฐ์ด ([0., 1., 2., 3., 4., NaN])
a [20] = nan # ์ด ์ถ๊ฐ
๊ณ ์ (a)
๋ฐฐ์ด ([0., 1., 2., 3., 4., NaN, NaN])
a [13] = nan
unique (a) # ๋ฐ 1/3
๋ฐฐ์ด ([0., 1., 2., 3., 4., NaN, NaN, NaN])
์ด๊ฒ์ ์๋ง๋ x์ y๊ฐ ๋ชจ๋ NaN์ด๋ฉด x == y๊ฐ False๋ก ํ๊ฐ๋๊ธฐ ๋๋ฌธ์ผ ๊ฒ์ ๋๋ค. Unique๋ ์ด๋ฏธ ์๋ณ ๋ ๊ฐ์ ๊ฐ์ด ์๋์ง ํ์ธํ๋ ์กฐ๊ฑด๋ฌธ์ "or (isnan (x) ๋ฐ isnan (y))"๋ฅผ ์ถ๊ฐํด์ผํฉ๋๋ค. ๋๋ numpy์์ ๋ ํนํ ์ถ์ด ์๋์ง ๋ชฐ๋๊ณ ๋ด๊ฐ ์ฐพ์๋ดค์ ๋ ๊ทธ๊ฒ์ ์ฐพ์ ์ ์์๊ธฐ ๋๋ฌธ์ ์ค์ค๋ก ๋ณ๊ฒฝํ ์ ์์ต๋๋ค (๋๋ ์กฐ๊ฑด ๋ฌธ์ ์ ํํ ๊ตฌ๋ฌธ์ด ๋ฌด์์ธ์ง ํ์ ํ ์๋ ์์ต๋๋ค).
๋ํ ๋ค์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ๋์์ ํจ์น ํ ์ ์์ต๋๋ค.
์ ์ nanunique (x) :
a = numpy.unique (x)
r = []
๋๋ฅผ ์ํด :
i๊ฐ r ๋๋ (numpy.isnan (i) ๋ฐ numpy.any (numpy.isnan (r))) ์ธ ๊ฒฝ์ฐ :
๊ณ์ํ๋ค
๊ทธ๋ฐ์:
r.append (i)
return numpy.array (r)
_trac ์ฌ์ฉ์ rspringuel์ด ์์ฑํ์ต๋๋ค. 2010-06-18_
์์ ์ฝ๋ ๋ธ๋ก์ ์ฌ์ฉํด์ผํฉ๋๋ค. ์ด๊ฒ์ ํจ์น ์ค๋ฒ ์ฝ๋์๋ง ์ค์ ๋ก ์ํฅ์ ๋ฏธ์น๋ฏ๋ก ๋ค์ ๊ฒ์ํ๊ฒ ์ต๋๋ค.
def nanunique(x):
a = numpy.unique(x)
r = []
for i in a:
if i in r or (numpy.isnan(i) and numpy.any(numpy.isnan(r))):
continue
else:
r.append(i)
return numpy.array(r)
๊ฒฐ์ ๋.
์ต์ ๋ง์คํฐ์์ ์ฌ์ ํ์ด ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ด๋ค ์ปค๋ฐ์ ์์ ํ์ด์ผํ๋์? ๋ด๊ฐ ๋ญ๊ฐ๋ฅผ ๋์น ๊ฒ์ด ์๋๋ผ๋ฉด์ด ๋ฌธ์ ๋ฅผ ๋ค์ ์ฌ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ด๊ฒ์ ์๋ ์ ๋ํด ์ฝ๊ฒ ๊ณ ์น ์ ์์ง๋ง ๋ณต์กํ๊ฑฐ๋ ๊ตฌ์กฐํ ๋ dtype์ ๋ํ ์ฌ์ด ๋ฐฉ๋ฒ์ ๋ณด์ด์ง ์์ต๋๋ค. ๊ฐ๋จํ PR์ ํจ๊ปํ๊ณ ๊ฑฐ๊ธฐ์์ ์ต์ ์ ๋ํด ๋ ผ์ ํ ์ ์์ต๋๋ค.
@jaimefrio ๊ณ ์ ์ฌ์ฉ์ ์ํด ์์ ํ์ต๋๋ค.
if issubclass(aux.dtype.type, np.inexact):
# nans always compare unequal, so encode as integers
tmp = aux.searchsorted(aux)
else:
tmp = aux
flag = np.concatenate(([True], tmp[1:] != tmp[:-1]))
ํ์ง๋ง ๋ค๋ฅธ ๋ชจ๋ ์์
์๋ ๋ฌธ์ ๊ฐ์๋ ๊ฒ ๊ฐ์ต๋๋ค. nan_equal, nan_not_equal
ufuncs ๋๋ nanfuntions๊ฐ ํ์ํ ์ ์์ต๋๋ค.
aux
์์ฒด๋ฅผ ์ ๋ ฌํ๋ ๊ฒ์ ํ๋ช
ํ ํธ๋ฆญ์
๋๋ค! ๋ชจ๋ ํญ๋ชฉ์ ์ ๋ ฌํ๋ ๊ฒ์ ์ฝ๊ฐ ๋ญ๋น์ด์ง๋ง ์ด์์ ์ผ๋ก๋ aux
๋ฐ flag
๋ฅผ ์ง๊ธ ๋น์ฅ ์์ฑ ํ ํ nan์ด์๋ ์ฒซ ๋ฒ์งธ ํญ๋ชฉ์ ์ฐพ์ ์ ์์ต๋๋ค. :
if not aux[-1] == aux[-1]:
nanidx = np.argmin(aux == aux)
nanaux = aux[nanidx:].searchsorted(aux[nanidx:])
flag[nanidx+1:] = nanaux[1:] != nanaux[:-1]
๋๋ ๋ด๊ฐ ๊ฑฐ๊ธฐ์ ๋์ ํ์ ๊ฐ๋ฅ์ฑ์ด์๋ ํ๋์ ์ค๋ฅ๋ก ๋ชจ๋ ์คํ๋ฅผ ์์ ํ ํ ๋น์ทํ ๊ฒ.
์ด ๋ง์ง๋ง ์ ๊ทผ ๋ฐฉ์์ float ๋ฐ ๋ณตํฉ ์ ํ์๋ ์๋ํ์ง๋ง ๋ถ๋ ์์์ ํ๋๊ฐ์๋ ๊ตฌ์กฐํ ๋ dtype์๋ ์คํจํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋๋ ๋ชจ๋ ์ ํ์ ๋ํด ์๋ํ๋๋ผ๋ ๊ฒ์ ์ ๋ ฌ ํธ๋ฆญ์ด ๋๋ฌด ๋ญ๋น๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๋ช ๊ฐ์ง ํ์ด๋ฐ :
In [10]: a = np.random.randn(1000)
In [11]: %timeit np.unique(a)
10000 loops, best of 3: 69.5 us per loop
In [12]: b = np.sort(a)
In [13]: %timeit b.searchsorted(b)
10000 loops, best of 3: 28.1 us per loop
์ด๋ 40 % ์ฑ๋ฅ ์ ํ๊ฐ ๋ ๊ฒ์
๋๋ค. nanunique
ํจ์์์๋ ๊ด์ฐฎ์ ์ ์์ง๋ง ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ์๋ ๊ทธ๋ ์ง ์์ ์ ์์ต๋๋ค.
2019 ๋ ์ OP ๋ฌธ์ ๋ ์ฌ์ ํ ์ ํจํ๋ฉฐ ์ฝ๋๋ ์ฌํ ๊ฐ๋ฅํฉ๋๋ค.
@jaimefrio ์ ์ฐ๋ฆฌ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฑฐ์ง ์ต์ ์ ๊ฐ์ง ์ ์์ต๋๊น?
๋ด ๋ง์,์ด ํ๋์ ๊ธฐ๊ปํด์ผ ํผ๋์ค๋ฝ๊ณ ์ฑ๋ฅ์ ๋ณ๋ช ์ด ์๋๋๋ค.
@ Demetrio92 ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๋ ์๋์ ๊ฐ์ฌ ๋๋ฆฌ์ง๋ง, ์ธํฐ๋ท์์ ์์ด๋ฌ๋ / ๋น๊ผฌ๋ ์ฌ๋๋ง๋ค ๋ค๋ฅด๊ฒ ํด์ ๋ ์ ์์ต๋๋ค. ์น์ ํ๊ฒ ์ ์งํด์ฃผ์ธ์. ์ฐ๋ฆฌ ์ค ์ผ๋ถ์๊ฒ๋ ์ฑ๋ฅ์ด ๋งค์ฐ ์ค์ํ๋ฉฐ ์์ ์๋๋ฅผ ๋ฆ์ถ๋ ์ฝ๋๋ฅผ ์์ฐ์ค๋ฝ๊ฒ ์ถ๊ฐํ์ง ์์ต๋๋ค.
PR # 5487์ ์์ผ๋ก ๋์๊ฐ ๋ฐฉ๋ฒ์ ๋ํด ์๊ฒฌ์ ๋งํ๊ฑฐ๋ ์ ์ํ๊ธฐ์ ๋ ์ข์ ๊ณณ์ผ ์ ์์ต๋๋ค.
ํธ์ง : PR ๋ฒํธ ์์
์ด ๋ฌธ์ ๋ 8 ๋
๋์ ์ด๋ ค์๋ ๊ฒ์ผ๋ก ๋ณด์ด์ง๋ง, numpy.unique
์ ๊ธฐ๋ณธ ๋์์ด ๋น ๋ฅด์ง ์๊ณ ์ ํํ๋๋ก +1์ํ๋ ค๊ณ ํฉ๋๋ค. ์ด๊ฒ์ ๋ด ์ฝ๋๋ฅผ ๊นจ๋จ ๋ ธ๊ณ ๋ค๋ฅธ ์ฌ๋๋ค์ด ๊ทธ๊ฒ์ผ๋ก ๊ณ ํต๋ฐ์ ๊ฒ์ด๋ผ๊ณ ํ์ ํฉ๋๋ค. ์ ํ์ "fast = False"๋ฅผ ๊ฐ์ง ์ ์์ผ๋ฉฐ fast ๋ฐ nans์ ๋ํ nan ๋์์ ๋ฌธ์ํ ํ ์ ์์ต๋๋ค. np.unique๊ฐ ์๊ฐ์ด ์ค์ํ ์์ฉ ํ๋ก๊ทธ๋จ์์ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ด ์์ฃผ ๋ฐ์ํ๋ค๋ฉด ๋๋ ๊ฒ์
๋๋ค.
์ค๋๋ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. np.unique ๋ฃจํด์ ํต์ฌ์ numpy / lib / arraysetops.py์ unraveled ์ ๋ ฌ ๋ ๋ฐฐ์ด์์ ๋ง์คํฌ๋ฅผ ๊ณ์ฐํ์ฌ ํด๋น ์ ๋ ฌ ๋ ๋ฐฐ์ด์์ ๊ฐ์ด ๋ณ๊ฒฝ๋๋์๊ธฐ๋ฅผ ์ฐพ๋ ๊ฒ์ ๋๋ค.
mask = np.empty(aux.shape, dtype=np.bool_)
mask[:1] = True
mask[1:] = aux[1:] != aux[:-1]
์ด๊ฒ์ ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ผ๋ก ๋์ฒด ๋ ์ ์์ต๋๋ค. ์ด๊ฒ์ ์ฝ 5 ๋ ์ ์ jaimefrio์ ์๊ฒฌ๊ณผ ๊ฑฐ์ ๋น์ทํ์ง๋ง argmin ํธ์ถ์ ํผํฉ๋๋ค.
mask = np.empty(aux.shape, dtype=np.bool_)
mask[:1] = True
if (aux.shape[0] > 0 and isinstance(aux[-1], (float, np.float16,
np.float32, np.float64))
and np.isnan(aux[-1])):
aux_firstnan = np.searchsorted(aux, np.nan, side='left')
mask[1:aux_firstnan] = (aux[1:aux_firstnan] != aux[:aux_firstnan-1])
mask[aux_firstnan] = True
mask[aux_firstnan+1:] = False
else:
mask[1:] = aux[1:] != aux[:-1]
๋ช ๊ฐ์ง % timeit ์คํ์ ์คํํ๋ฉด ์ด๋ ์ด๊ฐ ํฌ๊ณ NaN์ด ๋งค์ฐ ์ ์ ๊ฒฝ์ฐ (1 ๋ฐฑ๋ง ๊ฐ ์ค 10 NaN) ์ต๋ <10 % ๋ฐํ์ ํจ๋ํฐ๊ฐ ๊ด์ฐฐ๋์์ผ๋ฉฐ, ์ด๋ฌํ ๋ํ ์ด๋ ์ด์ ๊ฒฝ์ฐ ์ค์ ๋ก ๋ง์ ๊ฒฝ์ฐ ๋ ๋น ๋ฅด๊ฒ ์คํ๋ฉ๋๋ค. NaN์.
๋ฐ๋ฉด์ ๋ฐฐ์ด์ด ์์ ๊ฒฝ์ฐ (์ : 10 ๊ฐ ํญ๋ชฉ) float ๋ฐ NaN์ ๋ํ ๊ฒ์ฌ๊ฐ ์๋์ ์ผ๋ก ๋น์ธ๊ณ ๋ฐํ์์ด ๋ฐฐ์๋ก ์ฌ๋ผ๊ฐ ์ ์๊ธฐ ๋๋ฌธ์ ์๋นํ ์ฑ๋ฅ ์ ํ๊ฐ ์์ต๋๋ค. ๋๋ฆฐ ์ํ์ด๊ธฐ ๋๋ฌธ์ NaN์ด ์์ด๋ ์ ์ฉ๋ฉ๋๋ค.
๋ฐฐ์ด์ NaN์ด์๋ ๊ฒฝ์ฐ NaN์ ๊ฒฐํฉํ์ฌ ๋ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํฉ๋๋ค. ๋ฐ๋ผ์์ด ๊ฒฝ์ฐ์๋ ์ํ๋ ๊ฒฐ๊ณผ (๋ชจ๋ NaN์ด ๋จ์ผ ๊ฐ ๊ทธ๋ฃน์ผ๋ก ๊ฒฐํฉ ๋จ)๋ฅผ ์ฝ๊ฐ ๋ ๋๋ฆฌ๊ฒ ์ป๋ ๊ฒ๊ณผ ์ํ์ง ์๋ ๊ฒฐ๊ณผ (์์ฒด ๊ฐ ๊ทธ๋ฃน์ ๊ฐ NaN)๋ฅผ ์ฝ๊ฐ ๋ ๋น ๋ฅด๊ฒ ์ป๋ ๊ฒ์ด ์ค์ ๋ก ๋ฌธ์ ์ ๋๋ค.
๋ง์ง๋ง์ผ๋ก,์ด ํจ์น๋ ๋ค์ ์์ ์ ๊ฐ์ด NaN์ ํฌํจํ๋ ๋ณตํฉ ๊ฐ์ฒด์ ๊ด๋ จ๋ ๊ณ ์ ๊ฐ ์ฐพ๊ธฐ๋ฅผ ์์ ํ์ง ์์ต๋๋ค.
a = np.array([[0,1],[np.nan, 1], [np.nan, 1]])
np.unique(a, axis=0)
์ฌ์ ํ ๋์์ฌ ๊ฒ์ ๋๋ค
array([[ 0., 1.],
[nan, 1.],
[nan, 1.]])
"์ด๋ ์ด์ NaN์ด์๋ ๊ฒฝ์ฐ NaN์ ๊ฒฐํฉํ์ฌ ๋ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํฉ๋๋ค. ์ด๊ฒ์ด ๋ชจ๋์ ์์ ์ ๋๋ค."
+1
๋ฐ๋ณต๋๋ ์์๋ฅผ ํฌํจํ๋ ๋ชฉ๋ก์ ๋ฐํํ๋ ํจ์ (์ : NaN์ด 1 ๊ฐ ์ด์์ธ ๋ชฉ๋ก)๋ "๊ณ ์ "๋ผ๊ณ ๋ถ๋ฅด์ง ์์์ผํฉ๋๋ค. NaN์ ๊ฒฝ์ฐ ๋ฐ๋ณต๋๋ ์์๊ฐ ํ์ํ ๊ฒฝ์ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ๋นํ์ฑํ๋๋ ํน์ํ ๊ฒฝ์ฐ (์ numpy.unique(..., keep_NaN=False)
์ฌ์ผํฉ๋๋ค.
@ufmayer PR ์ ์ถ!
+1
NaN ๋ฐํ๋ ํ ๋ฒ๋ง ์ง์ํฉ๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ค๋๋ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. np.unique ๋ฃจํด์ ํต์ฌ์ numpy / lib / arraysetops.py์ unraveled ์ ๋ ฌ ๋ ๋ฐฐ์ด์์ ๋ง์คํฌ๋ฅผ ๊ณ์ฐํ์ฌ ํด๋น ์ ๋ ฌ ๋ ๋ฐฐ์ด์์ ๊ฐ์ด ๋ณ๊ฒฝ๋๋์๊ธฐ๋ฅผ ์ฐพ๋ ๊ฒ์ ๋๋ค.
์ด๊ฒ์ ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ผ๋ก ๋์ฒด ๋ ์ ์์ต๋๋ค. ์ด๊ฒ์ ์ฝ 5 ๋ ์ ์ jaimefrio์ ์๊ฒฌ๊ณผ ๊ฑฐ์ ๋น์ทํ์ง๋ง argmin ํธ์ถ์ ํผํฉ๋๋ค.
๋ช ๊ฐ์ง % timeit ์คํ์ ์คํํ๋ฉด ์ด๋ ์ด๊ฐ ํฌ๊ณ NaN์ด ๋งค์ฐ ์ ์ ๊ฒฝ์ฐ (1 ๋ฐฑ๋ง ๊ฐ ์ค 10 NaN) ์ต๋ <10 % ๋ฐํ์ ํจ๋ํฐ๊ฐ ๊ด์ฐฐ๋์์ผ๋ฉฐ, ์ด๋ฌํ ๋ํ ์ด๋ ์ด์ ๊ฒฝ์ฐ ์ค์ ๋ก ๋ง์ ๊ฒฝ์ฐ ๋ ๋น ๋ฅด๊ฒ ์คํ๋ฉ๋๋ค. NaN์.
๋ฐ๋ฉด์ ๋ฐฐ์ด์ด ์์ ๊ฒฝ์ฐ (์ : 10 ๊ฐ ํญ๋ชฉ) float ๋ฐ NaN์ ๋ํ ๊ฒ์ฌ๊ฐ ์๋์ ์ผ๋ก ๋น์ธ๊ณ ๋ฐํ์์ด ๋ฐฐ์๋ก ์ฌ๋ผ๊ฐ ์ ์๊ธฐ ๋๋ฌธ์ ์๋นํ ์ฑ๋ฅ ์ ํ๊ฐ ์์ต๋๋ค. ๋๋ฆฐ ์ํ์ด๊ธฐ ๋๋ฌธ์ NaN์ด ์์ด๋ ์ ์ฉ๋ฉ๋๋ค.
๋ฐฐ์ด์ NaN์ด์๋ ๊ฒฝ์ฐ NaN์ ๊ฒฐํฉํ์ฌ ๋ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํฉ๋๋ค. ๋ฐ๋ผ์์ด ๊ฒฝ์ฐ์๋ ์ํ๋ ๊ฒฐ๊ณผ (๋ชจ๋ NaN์ด ๋จ์ผ ๊ฐ ๊ทธ๋ฃน์ผ๋ก ๊ฒฐํฉ ๋จ)๋ฅผ ์ฝ๊ฐ ๋ ๋๋ฆฌ๊ฒ ์ป๋ ๊ฒ๊ณผ ์ํ์ง ์๋ ๊ฒฐ๊ณผ (์์ฒด ๊ฐ ๊ทธ๋ฃน์ ๊ฐ NaN)๋ฅผ ์ฝ๊ฐ ๋ ๋น ๋ฅด๊ฒ ์ป๋ ๊ฒ์ด ์ค์ ๋ก ๋ฌธ์ ์ ๋๋ค.
๋ง์ง๋ง์ผ๋ก,์ด ํจ์น๋ ๋ค์ ์์ ์ ๊ฐ์ด NaN์ ํฌํจํ๋ ๋ณตํฉ ๊ฐ์ฒด์ ๊ด๋ จ๋ ๊ณ ์ ๊ฐ ์ฐพ๊ธฐ๋ฅผ ์์ ํ์ง ์์ต๋๋ค.
์ฌ์ ํ ๋์์ฌ ๊ฒ์ ๋๋ค