https://numpy.org/doc/1.18/reference/generated/numpy.vectorize.html
์ด ํํ ๋ฆฌ์ผ์์๋ ๋ฒกํฐํ์ ๊ตฌํ์ด ๋ณธ์ง์ ์ผ๋ก for ๋ฃจํ๋ผ๊ณ ์ธ๊ธํฉ๋๋ค. ํ์ง๋ง ๋ด๊ฐ ์๋ ํ, ๋ฒกํฐํ ๋ ํจ์๋
SIMD, ๊ทธ๋์ numpy.vectorize์ ๊ตฌํ์ด ๋ณธ์ง์ ์ผ๋ก for ๋ฃจํ๋ผ๊ณ ๋งํ๋ ๊ฒ์ด ์ ํํฉ๋๊น? true์ด๋ฉด C ์ธ์ด๋ก ๊ตฌํ ๋ ๋ฃจํ์ด๊ธฐ ๋๋ฌธ์ ๋ฒกํฐํ๋์ง ์์ func๋ณด๋ค ๋น ๋ฆ ๋๋ค.
๋ฏธ๋ฆฌ ๊ฐ์ฌ๋๋ฆฝ๋๋ค.
์. Python (numpy ํฌํจ) ๋ฐ MATLAB โข๊ณผ ๊ฐ์ ํด์ ๋ ์ซ์ ๋ฐฐ์ด ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ๋งฅ๋ฝ์์ ์ข
์ข
"๋ฒกํฐํ"๋ฅผ ์ฌ์ฉํ์ฌ ํด์ ๋ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ๋ช
์ ์ ๋ฃจํ๋ฅผ ๋ชจ๋ ๊ฒ์ ์ฒ๋ฆฌํ๋ ํจ์ (๋๋ ์ฐ์ฐ์)๋ก ๋์ฒดํ๋ ๊ฒ์ ๋ํ๋
๋๋ค. ๋ด๋ถ์ ์ผ๋ก ๋
ผ๋ฆฌ ๋ฃจํ. numpy์์ ufunc
๋์ด ๋
ผ๋ฆฌ๋ฅผ ๊ตฌํํฉ๋๋ค. ์ด๊ฒ์ ๋ ๋ค ์ ์ฌํ ์์ ๋ฅผ ์ฌ์ฉํ๋ค๋ ์ ์ ์ ์ธํ๊ณ ๋ ๋์์ ์ฌ๋ฌ ์
๋ ฅ์ ๋ํด ๊ณ์ฐํ๋ SIMD CPU ๋ช
๋ น์ ์ฌ์ฉํ๋ "๋ฒกํฐํ"์ฌ์ฉ๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค. ์ด๋ค์ "์ค์นผ๋ผ"๋์ ๋ฌผ๊ณผ ๋น์ทํ์ง๋ง ์ฌ๋ฌ ์
๋ ฅ ๊ฐ์ ๋ํด ๊ณ์ฐ์ ์ํํฉ๋๋ค. ํ ๋ฒ์ ํธ์ถ๋ก.
numpy.vectorize()
์ฌ์ฉํ๋ฉด ์ผ๋ฐ์ ์ผ๋ก ๋ช
์์ ์ธ Python for
๋ฃจํ์ ๋นํด ์๋ ์ด์ ์ด ๋ง์ง ์์ต๋๋ค. ๊ทธ๊ฒ์ ์์ ์ ํ์ด์ฌ ํจ์๋ฅผ ufunc
๋ก ๋ฐ๊พธ๋ ๊ฒ์ธ๋ฐ, ์ด๊ฒ์ ๋ชจ๋ ๋ฐฉ์ก ์๋ฏธ๋ฅผ ๊ตฌํํ๊ณ ๋ฐ๋ผ์ ์ด๋ค ํฌ๊ธฐ์ ์
๋ ฅ๋ ์ฒ๋ฆฌํฉ๋๋ค. "๋ฒกํฐํ"๋๋ Python ํจ์๋ ์ฌ์ ํ ๋๋ถ๋ถ์ ์๊ฐ์ ์ฐจ์งํ๋ฉฐ ๊ฐ ์์์ ์์ ๊ฐ์ ํจ์์ ์ ๋ฌํ Python ๊ฐ์ฒด๋ก ๋ณํํฉ๋๋ค. np.vectorize(lambda x, y: x + y)
๊ฐ ๋ฃจํ์ ๋ฃจํ์ ๋ด์ฉ ๋ชจ๋์์ C ์ธ ufunc np.add
๋งํผ ๋น ๋ฅด๋ค๊ณ ๊ธฐ๋ํ์ง ์์ต๋๋ค.
์์ธํ ์ค๋ช ๊ฐ์ฌํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ช ํํ๊ฒ ์๋ฅผ ๋ค์ด ๋ณด๊ฒ ์ต๋๋ค.
import pandas as pd
import numpy as np
df = pd.DataFrame({'a': range(100000), 'b': range(1, 1000001)})
# method1
df.loc[:, 'c'] = df.apply(lambda x: x['a'] + x['b'], axis=1)
# method2
df.loc[:, 'c'] = np.vectorize(lambda x, y: x + y)(df['a'], df['b'])
# method3
df.loc[:, 'c'] = np.add(df['a'], df['b'])
๊ทธ๋์ ๋น์ ์ ์ค๋ช ๊ณผ ํจ๊ป
๋ฐฉ๋ฒ | C์ ๋ฃจํ | C์ ๋ฃจํ ๋ด์ฉ | SIMD ์ฌ์ฉ
-| -| -| -
1 | ร | ร | ร
2 | โ | ร | ร
3 | โ | โ | โ
๊ถ๋ฆฌ?
np.add
๋ C double์ Python ๊ฐ์ฒด๋ก ๋ณํํ๊ณ Python ํจ์ ํธ์ถ ์ค๋ฒ ํค๋๋ฅผ ๋ฐฉ์งํ๋ฏ๋ก np.vectorize(lambda x, y: x + y)
๋ณด๋ค ๋น ๋ฆ
๋๋ค. AVX2 ํ์ฅ์ด ์๋์ง ์ฌ๋ถ์ ๋ฐ๋ผ SIMD ๋ช
๋ น์ด๋ฅผ ์ฌ์ฉํ ์๋ ์์ง๋ง ์ด๊ฒ์ด ๋ ๋น ๋ฅธ ์ด์ ๋ ์๋๋๋ค.
np.add
๋ C double์ Python ๊ฐ์ฒด๋ก ๋ณํํ๊ณ Python ํจ์ ํธ์ถ ์ค๋ฒ ํค๋๋ฅผ ๋ฐฉ์งํ๋ฏ๋กnp.vectorize(lambda x, y: x + y)
๋ณด๋ค ๋น ๋ฆ ๋๋ค. AVX2 ํ์ฅ์ด ์๋์ง ์ฌ๋ถ์ ๋ฐ๋ผ SIMD ๋ช ๋ น์ด๋ฅผ _also_ ์ฌ์ฉํ
์์์ด. ๊ฐ์ฌ.
numba์ vectorize
๋ฅผ ์ฌ์ฉํ์ฌ Python ์ค๋ฒ ํค๋์์ด ๋ณ๋ ฌ๋ก ์๋ํ๋ ufunc๋ฅผ ์์ฑ ํ ์ ์์ต๋๋ค.
https://numba.pydata.org/numba-doc/latest/user/vectorize.html
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์. Python (numpy ํฌํจ) ๋ฐ MATLAB โข๊ณผ ๊ฐ์ ํด์ ๋ ์ซ์ ๋ฐฐ์ด ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ๋งฅ๋ฝ์์ ์ข ์ข "๋ฒกํฐํ"๋ฅผ ์ฌ์ฉํ์ฌ ํด์ ๋ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ๋ช ์ ์ ๋ฃจํ๋ฅผ ๋ชจ๋ ๊ฒ์ ์ฒ๋ฆฌํ๋ ํจ์ (๋๋ ์ฐ์ฐ์)๋ก ๋์ฒดํ๋ ๊ฒ์ ๋ํ๋ ๋๋ค. ๋ด๋ถ์ ์ผ๋ก ๋ ผ๋ฆฌ ๋ฃจํ. numpy์์
ufunc
๋์ด ๋ ผ๋ฆฌ๋ฅผ ๊ตฌํํฉ๋๋ค. ์ด๊ฒ์ ๋ ๋ค ์ ์ฌํ ์์ ๋ฅผ ์ฌ์ฉํ๋ค๋ ์ ์ ์ ์ธํ๊ณ ๋ ๋์์ ์ฌ๋ฌ ์ ๋ ฅ์ ๋ํด ๊ณ์ฐํ๋ SIMD CPU ๋ช ๋ น์ ์ฌ์ฉํ๋ "๋ฒกํฐํ"์ฌ์ฉ๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค. ์ด๋ค์ "์ค์นผ๋ผ"๋์ ๋ฌผ๊ณผ ๋น์ทํ์ง๋ง ์ฌ๋ฌ ์ ๋ ฅ ๊ฐ์ ๋ํด ๊ณ์ฐ์ ์ํํฉ๋๋ค. ํ ๋ฒ์ ํธ์ถ๋ก.numpy.vectorize()
์ฌ์ฉํ๋ฉด ์ผ๋ฐ์ ์ผ๋ก ๋ช ์์ ์ธ Pythonfor
๋ฃจํ์ ๋นํด ์๋ ์ด์ ์ด ๋ง์ง ์์ต๋๋ค. ๊ทธ๊ฒ์ ์์ ์ ํ์ด์ฌ ํจ์๋ฅผufunc
๋ก ๋ฐ๊พธ๋ ๊ฒ์ธ๋ฐ, ์ด๊ฒ์ ๋ชจ๋ ๋ฐฉ์ก ์๋ฏธ๋ฅผ ๊ตฌํํ๊ณ ๋ฐ๋ผ์ ์ด๋ค ํฌ๊ธฐ์ ์ ๋ ฅ๋ ์ฒ๋ฆฌํฉ๋๋ค. "๋ฒกํฐํ"๋๋ Python ํจ์๋ ์ฌ์ ํ ๋๋ถ๋ถ์ ์๊ฐ์ ์ฐจ์งํ๋ฉฐ ๊ฐ ์์์ ์์ ๊ฐ์ ํจ์์ ์ ๋ฌํ Python ๊ฐ์ฒด๋ก ๋ณํํฉ๋๋ค.np.vectorize(lambda x, y: x + y)
๊ฐ ๋ฃจํ์ ๋ฃจํ์ ๋ด์ฉ ๋ชจ๋์์ C ์ธ ufuncnp.add
๋งํผ ๋น ๋ฅด๋ค๊ณ ๊ธฐ๋ํ์ง ์์ต๋๋ค.