PandasãNumPyã®äžŠååŠçã ã£ãããã¡ã¢ãªã«ä¹ãåããªãããŒã¿ãæ±ãéãªã©ã«ããèŠãããDaskã©ã€ãã©ãªã
ãã ã现ãããšãããŸã§è§ŠããŠããæ¥æ¬èªã®è³æãããŸãç¡ãã£ãã®ã§ãå
¬åŒããã¥ã¡ã³ããªã©ããã£ããèªãã§ã¿ãŠãŸãšããŠã¿ãŸããã
â»Daskã®ããã¥ã¡ã³ãæ¢ã«èªãŸããŠããæ¹ã¯ãåç¥ããšæããŸãããããã¥ã¡ã³ããããªãã®ããªã¥ãŒã ãªã®ãšã现ããæãŸã§ææ¡ããã®ãç®çãšãããããæ¬èšäºãé·ãã§ããä»äºãªã©ã®éœåã§ããã£ãšäœ¿ããããæ¹ã«ã¯åããŠãããŸããã®ã§ããããã£ãå Žåã¯å¥ã®èšäºããåç §ãã ããã
ã©ããªã©ã€ãã©ãªãªã®ã
- Pythonã§äžŠååŠçã»åæ£åŠçãªã©ãç°¡åã«æ±ã£ãŠãããã
- Pythonã§ãã䜿ãããã©ã€ãã©ãªãšããªãè¿ãã€ã³ã¿ãŒãã§ã€ã¹ãæäŸããŠããïŒNumPyãPandasãScikit-Learnãäžå¿ã«ãä»ã«ãTensorFlowã»XGBoostãªã©ãïŒã
- å¿
èŠãªå Žåã«ã¯ãPySparkãªããã§ãããããªãè€æ°ã®ãã·ã³ãçšæããŠåæ£åŠçã§ã¹ã±ãŒã«ã¢ããããããéã«ã³ã¹ããäžããããã«æ°è»œã«ã¹ã±ãŒã«ããŠã³ããããªã©ãã§ããã
- â»ãã ããæåã¯1ã€ã®ãã¹ã¯ãããã§äœ¿ãå§ãã人ã倧åãšã®ããšã
- â»1000å°ãšããããã§ããã°ãååå¹ççã«åŠçããŠããããããã
- æåã©ã€ãã©ãªã ãã§ã¯ãªããPythonèªäœã®ã³ãŒãããããªã«ããããŠç°¡åã«äžŠååãããããŠãããæ©èœããããPandasãNumPyã®ã€ã³ã¿ãŒãã§ã€ã¹ã ãšå¯Ÿå¿ãé£ããéã«ãç¬èªã®ã³ãŒããæžããŠäŸå€çãªè€éãªã¿ã¹ã¯ãªã©ã«ãæè»ã«å¯Ÿå¿ãã§ããã
- ããŒã¿ãå šãŠã¡ã¢ãªã«ä¹ãããéšåçãªãããŸãåäœã§ã¡ã¢ãªã«ä¹ãããããŠèšç®ããã®ã§ãéåžžã¯Pandasãªã©ã§ã¡ã¢ãªã«ä¹ãåããªã倧ããªããŒã¿ã»ããã§ãæ±ããã
- Daskãçµç±ããåŸã®çµæã®ããŒã¿ã¯ãNumPyé åãPandasã®ããŒã¿ãã¬ãŒã ãªã©ã«ãªãããã®ããã倧ããªããŒã¿ã®èªã¿èŸŒã¿ãã¹ã©ã€ã¹ãéè€åé€ãªã©ã®åŠçãè¡ã£ãŠè¡æ°ãæžãããŠPandasãªã©ã§å¿«é©ã«å¶åŸ¡ã§ããããŒã¿èŠæš¡ã«ããŠãããããã«çްããèšç®ãªã©ã¯PandasãNumPyé åã§ç¶ç¶ããŠè¡ããšãã£ããããŒãå¿«é©ã«è¡ããã
- NumPyãPandasãScikit-Learnãªã©ã®çœ®ãæããšãªãã©ã€ãã©ãªã§ã¯ãªããã©ã¡ãããšãããšãããã®ã©ã€ãã©ãªãããå¿«é©ã«äœ¿ããããã«æ¡åŒµããã©ã€ãã©ãªã®ãããªã€ã¡ãŒãžãå éšã§ããããã®ã©ã€ãã©ãªãå®éã«äœ¿ãããŠããã®ã§ãããšãã°Pandasã®æ¹åããã®ãŸãŸDaskã«ãæ¹åç¹ãšããŠåæ ããããããããããã£ãç«ã¡äœçœ®ã§ããã®ã§ãåè¿°ã®ã©ã€ãã©ãªãJupyterãªã©ã®ã©ã€ãã©ãªã®ã³ãã¥ããã£ãšå¯ã«é£æºãã€ã€éçºãé²ããããŠãããããã
- 2019幎çŸåšãGithubã®ã¹ã¿ãŒæ°ãçŽ5000ãcontributorã®æ¹ã250åããããçŸåšãé »ç¹ã«éçºãé²ããããŠããã
ã©ããªãšãã«DaskãåããŠããã®ãã®äŸ
Daskãè²ã
䟿å©ã«äœ¿ããäžæ¹ã§ãéã®åŒŸäžžãšãããã®ã§ããªãã
ä»ã®æ§ã
ãªã©ã€ãã©ãªåæ§ã¡ãªãããã¡ãªããããã®ã§ãDaskã«åããŠããç®æã«Daskã䜿ã£ãŠãä»ã®ãã®ã®ã»ããåããŠããã±ãŒã¹ã§ã¯ä»ã®ãã®ã䜿ã£ãã»ãããããšæãããã以äžã§å€§éæã«åããŠããç¹ã»åããŠããªãç¹ã®ç¹åŸŽãã³ãŒãã«è§ŠããŠããåã«èšèŒïŒé·ãèšäºãªã®ã§ãèªãã¹ãèšäºãªã®ãã®å€æçšãšããŠå
ã«åããŠããç¹ã»åããŠããªãç¹ãèšèŒïŒã
- æ®éã«æ±ããšã¡ã¢ãªãè¶³ããªãã±ãŒã¹ : Pandasãªã©ã§ã¯æ®éã¯æ±ããªãèŠæš¡ã®ããŒã¿ã§ãã1ã€ã®ãã¹ã¯ãããã§ãæ±ããããã«ãªãã
- åŠç¿ã³ã¹ããæãããå Žå : NumPyã»Pandasã»Scikit-Learnã»ãããã¯Pythonèªäœã®ã³ãŒãã§ãæ £ããã€ã³ã¿ãŒãã§ã€ã¹ã§æ±ããã®ã§ãããã£ãšäœ¿ãå§ããããšãã§ãããéèšãªã©ãæ¶åããã®ãç®çã§ãæ°ããã©ã€ãã©ãªãåŠã¶æéãæžãããŠä»ã®ããšã«æ³šåãããå Žåã
- æ¢ã«NumPyãPandasãªã©ã§æžãããã¹ã¯ãªãããªã©ã®è³ç£ããããæ¹åãå¿ èŠãªå Žå : ããã®è³ç£ãã¡ã¢ãªçã«ãã€ããªã£ãŠããããããé«éåãå¿ èŠã«ãªã£ãéã«æžãçŽãã®ã³ã¹ããäœãæãã€ã€æ¹åãããå Žåãªã©ãæžãçŽãã¯ãå°å³ã§çµæ§ããã©ãäœæ¥ãªã®ã§ãããã軜æžããããšããã®ã¯çµæ§å©ããã±ãŒã¹ãããã
- 1ã€ã®PCã§æåã¯é²ããŠãããã®ã®ã段ã 忣åŠçãå¿ èŠãªã¬ãã«ã«ãªã£ãŠããå Žå : Daskã§ã¯1ã€ã®ãã·ã³ã§ã®èšç®ã忣ç°å¢ã§ã®èšç®ã察å¿ããŠãããããã³ãŒãã®æžãçŽãã®æéãå°ãªãæãã€ã€éäžã§åãæ¿ããŠããããéã«ãã¹ã±ãŒã«ããŠã³ããŠã³ã¹ããäžããããããããããããã
- 倧éã®ããŒã¿ã«å¯ŸããŠãããŒã¿ãäœåºŠã確èªãããã調æŽããããšãæ¢çŽ¢çã«æ±ãå¿ èŠãããå Žå : BigQueryãAthenaãªã©ã§SQLã§æ±ããããã¯ãPandasãªã©ã®æèŠã§Pythonã§æ±ã£ãã»ããé·ãèšç®ãªã©ã§ã¯èª¿æŽãããããã£ãããSQLãè€éã«ãªããããããé¿ããããã
-
ããŒã¿ãµã€ãšã³ãã£ã¹ãã®ããŒããªã©ããšã³ãžãã¢ãè² è·ãäžãã€ã€æ¬çªã«åæ ãããå Žå :
ããŒã¿ãµã€ãšã³ãã£ã¹ãããNumPyãPandasãScikit-Learnãªã©ã䜿ã£ãJupyterããŒããããã£ãŠãAIãšã³ãžãã¢ãããã¯ããŒã¿ãšã³ãžãã¢ãæ¬çªç°å¢ã«ä¹ããŠããéã«ãã³ãŒãããªãã¹ããã®ãŸãŸã«ãã€ã€ãäžã€æ¬çªãžã®åœ±é¿ãå°ãªãããããã«ãã¥ãŒãã³ã°ãã¡ã¢ãªäœ¿çšéãäœãæãããå Žåã - ããŒã¿ãå€ãã®CSVãHDF5ãªã©ã®æ§ã ãªãã©ãŒãããã§ä¿åãããŠããå Žå : Pandasåæ§ãèªã¿èŸŒã¿ã«æ§ã ãªãã©ãŒãããã«å¯Ÿå¿ããŠããããŸããè€æ°ã®ãã¡ã€ã«ãåå¥ã«èªã¿èŸŒãã§åŸã§pd.concatãªã©ããªããŠãã1è¡æžãã ãã§äžŠåã§å®è¡ããŠãããŠãconcatãªã©ã®æéãçããŠãããããªã©ãããŒã«ã«ã§æç³»åãªã©ã§å€ãã®ãã¡ã€ã«ãããå Žåã«ãå¿«é©ã«åŠçãã§ããã
DaskãåããŠããªããããããªãã±ãŒã¹ã®äŸ
- èšç®ãç¹ã«è€éã«ã¯ãªãããSQLã ãã§ååãªå Žå : 忣ç°å¢ãçšæããã³ã¹ãããé床ã管çã®æ¥œããªã©ãèãããšãæ®éã«BigQueryãAthenaãªã©ã§ããå°è±¡ãããŠããããã ããã©ã¡ããäžæ¹ã§ã¯ãªããããšãã°S3ã«CSVãšãã§ããŒãã£ã·ã§ã³èšå®ãããããã£ã¬ã¯ããªæ§æã§çœ®ããŠããã°Daskã§ãAthenaã§ãã©ã¡ãã§ãå¹ççã«æ±ããã®ã§ãã¿ã¹ã¯ã«å¿ããŠäœ¿çšãããã®ãåãæ¿ããããããã¯äœµçšãããã§ãã圢ã«ããŠãããšããã®ã奜ãŸãããããããªãã
- æ¢åã®Pandasãªã©ã®ã³ãŒãè³ç£ãªã©ã¯é¢ä¿ãªããäžã€ããŒã¿ãHDF5ãªã©ã§æ±ããŠãé床ãéèŠãªå Žå : æããvaexãªã©ã®ã»ããåããŠãããé床èªäœã¯vaexã®æ¹ã倧åéãããªå°è±¡ããããïŒvaexã¯ãã£ããã¢ããã§ããŠããªãã®ã§è©³çްã¯å²æã»ã»HDF5ã®ãªã©ã€ãªãŒæ¬ã¯æ³šæããã®ã§ãããæ©äŒãããã°å°æ¥ãŸãšããã»ã»ããïŒ
- 1ã€ã®ãã·ã³ã§æ±ãå¿ èŠãããããããDaskã§ãæ±ããããªãã¬ãã«ã®ããŒã¿ã»ããã®å Žå : Pandasãªã©ã«æ¯ã¹ãã°ãããŸãåäœã§éšåçã«ã¡ã¢ãªã«ä¹ããããŠåŠçãããã®ã§ã倧åçã¡ã¢ãªã§æ±ããäžæ¹ã§ããããŸãã现ããåå²ãããããšåå²ã«ãããªãŒããŒãããã§Daskã§ããŸãšãã«æ±ããªããªã£ãŠããããããã£ãå Žåã¯BigQueryãªã©ã«é Œããã忣åŠçãæ€èšããããä»ã®ã©ã€ãã©ãªãæ€èšããããªã©ãå¿ èŠã«ãªã£ãŠãããåèš100GBã®CSVãªã©ã§ããã°äœè£ã§1ã€ã®PCã§æ±ããäžæ¹ã§ãåèš1TBã倧ããè¶ ãããããªCSVãªã©ã§ããã°ã©ãããŠãã¡ã¢ãªãããããç©ãã PCãããªããšå¹çé¢ã§å³ãããªã£ãŠããã
- ããããå°èŠæš¡ãªããŒã¿ã»ãã : äœè£ã§ã¡ã¢ãªã«ä¹ãåããå°ããããŒã¿ãªã©ã§ããã°Daskã䜿ããã«ãã®ãŸãŸPandasãNumPyãªã©ãå©çšããã®ã奜ãŸããã±ãŒã¹ãå€ããPandasãªã©ãšäŒŒããããªã€ã³ã¿ãŒãã§ã€ã¹ãšãã£ãŠããããçšåºŠã¯Daskã䜿ãããšã§è€éã«ãªã£ããç¡é§ã«ãªãŒããŒãããã絡ãã§ãããããã®ã§ãéé²ã«Daskã«æžãæããã®ã§ã¯ãªããç¹ã«ããŒã¿éçã«åé¡ãªããäžã€ä»åŸãæ¥æ¬¡ã®ããŒã¿ãªã©ãå¢å ããŠãããªãããŒã¿ã§ããã°ã·ã³ãã«ã«Pandasãªã©ã䜿ãã
- åçŽã«é«éåã®ã¿ãå¿ èŠãªå Žå : ã¡ã¢ãªãªã©ã¯ç¹ã«åé¡ã«ã¯ãªããªããã®ã®ãèšç®ãªã©ã®é«éåã®ã¿ãå¿ èŠãªå Žåã«ã¯ãããããããCythonãNumbaãPyPyãªã©ã®æ¹ãåããŠãããããããªãããããã¯é©ããããŒã¿æ§é ãéžæããã°ãDaskãå°å ¥ããªããŠãååèŠä»¶ãæºããããããããªããïŒåè : PythonãéãããTIPSéïŒèšæž¬ã»ãã«ãã€ã³ã®åæ©èœã»Cythonã»Numbaã»etcïŒïŒ
Daskã®å¶é
詊ããŠã¯ããªããã®ã®ã1ã€ã®ãã·ã³ã§50ã³ã¢ãè¶ ããã¬ãã«ã«ãªã£ãŠãããšãã¹ã±ãŒã«ããã以äžã¯ã§ããªãããïŒãšããå°è±¡ã®èšè¿°ãããã¥ã¡ã³ãã«ãã£ãã
They scale their algorithm between 1 and 50 cores on single workstations
å ¬åŒããã¥ã¡ã³ã Use Casesããã
ãããŸã§ã®ãã·ã³ãäœ¿ãæ©äŒã¯ã»ãŒãªãããïŒæè¿ïŒ2019幎ïŒçºè¡šãããMac Proã§ãMax28ã³ã¢ãããïŒïŒã§ã¯ãããã®ã®ãã¯ã©ãŠãã€ã³ã¹ã¿ã³ã¹ãªã©ãå©çšããå Žåã¯ããããããåŒã£ããããããããªãã
ãã以äžã«é«éåãªã©ãå¿
èŠã§ããã°ã1ã€ã®ãã·ã³ããšã«ããã¹ããã¯ã¢ããããã®ã§ã¯ãªããè€æ°ã®ãã·ã³ã§ã®Daskã®åæ£åŠçãªã©ãæ€èšããå¿
èŠãããã
æ¬èšäºã§æ±ãDaskã®å 容
- Pandasã®ã€ã³ã¿ãŒãã§ã€ã¹ïŒDask DataFrameïŒ
- NumPyã®ã€ã³ã¿ãŒãã§ã€ã¹ïŒDask ArrayïŒ
- Pythonèªäœã®ã€ã³ã¿ãŒãã§ã€ã¹ïŒDask DelayedïŒ
- Daskã®ããã©ãŒãã³ã¹TIPSããããã¡ã€ãªã³ã°
- ãããã°TIPS
æ¬èšäºã§æ±ããªãDaskã®å 容
- Pythonã®ã€ã³ã¿ãŒãã§ã€ã¹ã®äžã§ãBagsã®è©³çްã ã£ããã峿ã§ã®èšç®ãèµ°ãã¿ã€ãã®ãã®ïŒFuturesïŒãªã©ã
- Scikit-Learnãªã©ã®æ©æ¢°åŠç¿é¢ä¿
- æ©æ¢°åŠç¿é¢ä¿ãé€ããŠãããã¥ã¡ã³ãã¯çµæ§ãªããªã¥ãŒã ã«ãªã£ãŠãããæ©æ¢°åŠç¿ãŸã§æãåºããšçžåœé·ããªããããªæ°é ãããããä»åã¯å²æã
- 忣åŠçé¢ä¿ïŒDask DistributedïŒ
- â»ä»ã®ãšããã¯1ã€ã®ãã·ã³ã§äœ¿ãäºå®ãªã®ãšãã»ãšãã©ã®æ¹ã1ã€ã®ãã·ã³ã§åãããšæããããå¿ èŠã«ãªã£ãŠããã調ã¹ãŠå¥ã®èšäºã«å¯Ÿå¿ã
ãµã³ãã«ã³ãŒããªã©ã§äœ¿ãç°å¢
- Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
- Ubuntu
- Jupyter notebook
- Dask==1.2.2
â»Windowsã§ã¯äžéšåããªãã±ãŒã¹ããããããããªãã
ã€ã³ã¹ããŒã«
Anacondaã䜿ã£ãŠããå Žåã¯æåããå ¥ã£ãŠããïŒããããAnacondaèªäœãDaskã®ã¡ã€ã³ã®ã¹ãã³ãµãŒã ã£ãããã³ããŒã©ã€ããèŠããšAnacondaã®è¡šèšãããïŒã
ãã ãã0.x.xç³»ãš1.x.xç³»ã ãšçµæ§ã€ã³ã¿ãŒãã§ã€ã¹ãéãïŒ0.x.xç³»ã«ç¡ãã€ã³ã¿ãŒãã§ã€ã¹ãªã©ãå€ãïŒã
確èªããŠã¿ãŠãããå€ããã°ã¢ããããŒãããã»ããç¡é£ãªå°è±¡ãããã
ããŒãžã§ã³ç¢ºèªæ¹æ³ :
import dask
dask.__version__
'0.14.3'
ããMinicondaãªã©ã䜿ã£ãŠããã±ãŒã¹ãªã©ã§ãDaskãå ¥ã£ãŠããªãã±ãŒã¹ã§ããã°ä»¥äžã®ããã«ã€ã³ã¹ããŒã«ããããšãã§ããã
$ conda install dask
pipã§ããã°ä»¥äžã®ããã«æå®ããã
$ pip install "dask[complete]"
â»ããŒãžã§ã³ã«ãã£ãŠã¯NumPyãPandasãªã©ã«ãæŽæ°ããããã®ã§ã倿Žããããªãå Žåã¯æ³šæãå¿ èŠãäºåã«å¥éAnacondaç°å¢ãçšæãããã圱é¿ãåºãªãDaskã®å€ãããŒãžã§ã³ãéžæãããªã©ãå¿ èŠã«ãªã£ãŠããã
[complete]ãšãã£ãããã«ãç¹æ®ãªæå®ã«ãªã£ãŠããã
ããã¯ãäŸåããŠããã©ã€ãã©ãªãªã©ãäžéãã€ã³ã¹ããŒã«ããæå®ãšãªã£ãŠãããpip install daskãšãããšãdaskèªäœã®æäœéã®ãã®ããã€ã³ã¹ããŒã«ãããªãïŒåããªãã¢ãžã¥ãŒã«ãçµæ§åºãŠããïŒã®ã§æ³šæãäŸåãããã®ãè²ã
ããã®ã§ãåºæ¬çã«ã¯æåã§äŸåé¢ä¿ã解決ããã«Daskã«ä»»ããã»ããç¡é£ãªå°è±¡ãããã
[complete]ã®ã»ãã«ãã以äžã®ããã«äžéšã ãã€ã³ã¹ããŒã«ããéžæè¢ãçšæãããŠããããã ããåºæ¬çã«ã¯æ¬çªç°å¢ã®ãã£ã¹ã¯å®¹éãå°ãã§ãç¯çŽããããšãã§ãªããã°åºæ¬çã«[complete]ã§ãããããªæ°ãããŠããã
-
NumPyã®ã€ã³ã¿ãŒãã§ã€ã¹ã®ã¿ãã€ã³ã¹ããŒã«ãã :
$ pip install "dask[array]" -
Pandasã®ã€ã³ã¿ãŒãã§ã€ã¹ã®ã¿ãã€ã³ã¹ããŒã«ãã :
$ pip install "dask[dataframe]" - etc...
ã€ã³ã¹ããŒã«ããŒãžã§ã³ãæå®ãããå Žåã«ã¯ãéåžžã®pipãšåæ§ã«==ã§æå®ããããšã§èšå®ã§ããã
$ pip install "dask[complete]"==1.2.2
â»ä»åã¯1.2.2ã䜿ã£ãŠããã®ã§ãäžèšã®ã³ãã³ãã§å¯Ÿå¿ããŠããã
importã®æ £ç¿
NumPyã®ã¢ãžã¥ãŒã«ããçãas npãšãã£ãããã«ããã®ãšåæ§ãDaskã§ãããã¥ã¡ã³ããèŠãŠããæãã§ã¯ã以äžã®ããã«çµ±äžãããŠimportã®asã®èšè¿°ããããŠããã
-
Dask é
å : Dask Arrayãšããããšã§ãdaãšãªã£ãŠããã
import dask.array as da -
Dask ããŒã¿ãã¬ãŒã : Dask DataFrameãšããããšã§ãddãšãªã£ãŠããã
import dask.dataframe as dd -
Bag : Dask Bagãšããããšã§ãdbãšãªã£ãŠããã
import dask.bag as db
Daskã®èšç®ã®ç¹é·
éåžžã®PandasãNumPyãªã©ã§ã®èšç®ãšç°ãªããèšç®ã®ã³ãŒãã§å³æã§èšç®ãèµ°ããªãã
ããšãã°ãNumPyã®ã€ã³ã¿ãŒãã§ã€ã¹ãšåãããã«ã以äžã®ããã«æžããŠããã®æç¹ã§ã¯ããŒã¿ãçšæãããããèšç®ãèµ°ã£ããã¯ããªãã
import dask.array as da
x = da.random.uniform(low=0, high=1.0, size=(300000000, 100))
y = x.max(axis=0).max()
3åè¡100åãšãããæ®éã«PandasãNumPyã§æ±ããšPCã®ã¹ããã¯ã«ãã£ãŠã¯ã²ãã£ãšããèŠæš¡ã®è¡åãæå®ããŠããã®æç¹ã§ã¯ã¡ã¢ãªãæ¥å¢ãããã¯ããªãã
å¿
èŠãªèšç®ãæžãçµãã£ãŠãcomputeã¡ãœãããåŒã³åºããæç¹ã§ããŒã¿ã確ä¿ãããèšç®ããŸãšããŠèµ°ãå§ããã
y.compute()
äžèšã®ããã«ãcomputeã¡ãœãããåŒã°ããæç¹ã§ã¡ã¢ãªãå€åãå§ããã
ãŸããããŒã¿ãããçšåºŠã®ãããŸãã§åå²ããŠããã®ãããŸãåäœã§ã¡ã¢ãªã«ä¹ã£ãŠèšç®ããããŠããïŒNumPyã€ã³ã¿ãŒãã§ã€ã¹ã§ã¯ãã£ã³ã¯ïŒchunkïŒãPandasã€ã³ã¿ãŒãã§ã€ã¹ã§ã¯ããŒãã£ã·ã§ã³ïŒpartitionïŒãšããåèªã§ããåºãŠããïŒã®ã§ãäžåºŠã«å
šãŠãã¡ã¢ãªã«ä¹ããNumPyãPandasãšæ¯ã¹ããšç¬éçãªã¡ã¢ãªã¯ãã£ãšäœãæããããã
åè¿°ã®ãµã³ãã«ã§ã¯ã3åè¡100åã®ããŒã¿ã§ããã¿ã€ãã³ã°ã§ããçšåºŠã°ãã€ããã®ã®ã倧äœ1GB匱çšåºŠã®ã¡ã¢ãªã§åŠçãã§ããŠããã
ãã®computeã®ã€ã³ã¿ãŒãã§ã€ã¹ã¯Daskã®åæ©èœã®ã€ã³ã¿ãŒãã§ã€ã¹ã§å
±éã§ååšããã
ãã ããNumPyã€ã³ã¿ãŒãã§ã€ã¹ã䜿ã£ãå Žåã¯computeåŸã®è¿åŽå€ã¯NumPyã®é
åãšãªããPandasã€ã³ã¿ãŒãã§ã€ã¹ã䜿ã£ãå Žåã¯Pandasã®ããŒã¿ãã¬ãŒã ãPythonã®ã€ã³ã¿ãŒãã§ã€ã¹ã䜿ã£ãå Žåã¯intãªã©ã®Pythonãªããžã§ã¯ãã«ãªããšããéããããã
éçšã§äœ¿ãããDaskã®ããŒã¿ã¯èšç®ãçµãã£ãŠNumPyãPandasã®ããŒã¿ã«ãªã£ãæç¹ã§ããã®ããŒã¿ã®ã¿ã®ã¡ã¢ãªã確ä¿ãããã
ã€ãŸããDaskã®èšç®ã®éçšã§ããŒã¿ã®èªã¿èŸŒã¿ããã¹ã©ã€ã¹ãªãéè€åé€ãªã©ãããããšã§ãæçµçã«ç¢ºä¿ãããã¡ã¢ãªãå°ããããããšãã§ããã
ãã®ããã«Pandasã®ããŒã¿ãã¬ãŒã ãNumPyã®é
åãå°ãããããŸã§ã®ç®æã ãDaskã§çœ®ãæããã°ããã®åŸã®ã³ãŒãã¯ãã®ãŸãŸPandasãNumPyã®ãŸãŸã§ãå¿«é©ã«èšç®ãªã©ãè¡ãªãããšãã§ãããïŒæ¢åã®ã³ãŒãã®çœ®ãæãããããããïŒ
â»éã«ããã°ãæçµçã«ã¡ã¢ãªã«å±éãããPandasã®ããŒã¿ãã¬ãŒã ããNumPyé åãã¡ã¢ãªã«åãŸããªããµã€ãºã®ãŸãŸã ãšãDaskãçµç±ããŠãçµå±ã¡ã¢ãªãè¶³ããªããªããDaskäžã§èšç®ãã¹ã©ã€ã¹ãªã©ãè¡ãªã£ãŠãæçµçãªããŒã¿ãå°ããããã®ã倧äºã
ãªãDask峿ã§èšç®ãèµ°ããªãããã«ãªã£ãŠããã®ãããšããç¹ã¯ã以äžã®ãããªçç±ãããããªã£ãŠããã
- å¿ èŠãªèšç®ãæžããŠãã£ãæç¹ã§ãcomputeã¡ãœããã®åã§ã©ããªæãã®ã¿ã¹ã¯ã°ã©ãïŒDaskäžã®èšç®ã°ã©ãã®ãããªãã®ãDaskã§ã¿ã¹ã¯åäœã§ã°ã©ãã«è¡šç€ºãããïŒãå¿ èŠãªã®ãã確å®ããã
- ãã®ç¢ºå®ããã¿ã¹ã¯ã°ã©ããåç §ããŠãDaskåŽã§ã©ã®ããã«äžŠååãããšå¹çãããã®ããã©ããªæãã«ããŒã¿ã®ãããŸããåããã»ããããã®ããå€å®ã§ãããçµæãšããŠãèšç®ãå¹ççã«å®è¡ãããã
ããã ãã ãšåããã¥ããã®ã§ãå®éã«Daskã®ã¿ã¹ã¯ã°ã©ãã®å¯èŠåã®æ©èœïŒåŸè¿°ïŒã䜿ã£ãŠèŠãŠã¿ããšã䞊ååãªã©ãã©ã®ããã«ãããã®ããã€ã¡ãŒãžãã€ããããã
x1 = da.random.uniform(low=0, high=1.0, size=(100, 100))
x2 = da.random.uniform(low=0, high=1.0, size=(100, 100))
x3 = da.random.uniform(low=0, high=1.0, size=(100, 100))
x4 = da.random.uniform(low=0, high=1.0, size=(100, 100))
y = x1 + x2 + x3 * x4
result_arr = y.compute()
äžèšã®ã³ãŒãã¯ä»¥äžã®ãããªã¿ã¹ã¯ã°ã©ãã«ãªãã
ã¿ã¹ã¯ã°ã©ããèŠããšãcomputeã®æç¹ã§å¿
èŠãªèšç®ã§ã¯ãæåã¯4ã€ã§äžŠååŠçãããŠããã®åŸ2ã€ãæåŸã«1ã€ã®ããŒããå¿
èŠãªããšãåããã
1è¡ãã€ãPandasã®ããã«å³æã§èšç®ããŠããŸããšãã©ã®ããã«äžŠååãã¹ããªã®ããåãããªãã
ãã ãã峿ã§èšç®ããããã»ãã䟿å©ãªãšããããã®ã§ããããã£ãå Žåã®ããã®æ©èœãçšæãããŠãããããããã¯computeãè€æ°æãïŒäžéããŒã¿ãæãïŒãšããäœ¿ãæ¹ãã§ããïŒãã®åã®PCãªãœãŒã¹ãå¿ èŠãšãããã¯ããïŒã
Daské åïŒNumPyã€ã³ã¿ãŒãã§ã€ã¹ïŒ
以éã§ã¯ãããã€ãã®ç¯ã«æž¡ã£ãŠNumPyã€ã³ã¿ãŒãã§ã€ã¹ã®Daské åïŒDask ArrayïŒã«é¢ããŠèšèŒã
Daské åã¯ä»¥äžã®ãããªç¹é·ãããã
- è¡åãããæ¬¡å ãæ·±ããã³ãœã«ãªã©ã§ããµã€ãºãã¡ã¢ãªã«åãŸããããªãããŒã¿ã«å¯ŸããŠèšç®ãè¡ãªããã
- æ§æãšããŠã¯ã以äžã®ããã«ããã€ãã®NumPyé åãã°ãªãããšããŠé 眮ãããç¶æ ã§æ§æãããããã®ã°ãªããã®åäœã¯ãããŸããšããæå³ã®ãã£ã³ã¯ïŒchunkïŒãšããåèªã§åŒæ°ãªã©ã§ããåºãŠããïŒããã©ãŒãã³ã¹ãèããäžã§éèŠã«ãªã£ãŠããã®ã§ã詳现ã¯åŸè¿°ïŒã
Daské åã§ãµããŒãããŠãããã®ã®äŸ
-
åºæ¬çãªæŒç®åŠç :
+ã%ã®ãªãã¬ãŒã¿ãŒãªã©ã§ã®åºæ¬çãªèšç®ã
import dask.array as da
arr_1 = da.from_array(x=[1, 2, 3])
arr_2 = da.from_array(x=[4, 5, 6])
arr_3 = arr_1 + arr_2
arr_3.compute()
array([5, 7, 9])
-
èŠçŽçµ±èšéé¢ä¿ :
sumãmeanãstdãªã©ã®é¢æ°ã
arr_1 = da.from_array(x=[1, 2, 3])
y = arr_1.sum()
y.compute()
6
- å ç©ãè¡åã®ä¹ç®ãªã© :
arr_1 = da.from_array(x=[1, 2, 3])
arr_2 = da.from_array(x=[4, 5, 6])
y = da.dot(a=arr_1, b=arr_2)
y.compute()
32
- 転眮 :
arr_1 = da.from_array(
x=[[1, 2, 3],
[4, 5, 6]])
y = arr_1.T
y.compute()
array([[1, 4],
[2, 5],
[3, 6]])
- ã¹ã©ã€ã¹é¢ä¿ :
arr_1 = da.from_array(x=[1, 2, 3, 4])
y = arr_1[arr_1 >= 3]
y.compute()
array([3, 4])
- ãã®ä» : APIã®ããã¥ã¡ã³ãããŒãžã«ããµããŒããããŠãã颿°ãªã©ãèšå€§ã«èšèŒãããŠãããNumPyèªäœãAPIãè²ã ããã®ã§ãDaskåŽã§ãAPIãèšå€§ã«ãªã£ãŠããã
åè¿°ã®éããäžéšcomputeãNumPyé
åãªã©ãããçæã§ããfrom_arrayãªã©ã®Daskç¹æã®ãã®ããã(da.from_arrayã¯np.arrayãšã»ãŒäŒŒããããªæèŠã§ã¯ãã)ãã®ã®ã倧äœã®ã€ã³ã¿ãŒãã§ã€ã¹ã¯NumPyãã£ããã§ãè¿åŽå€ã®æåã銎æã¿ãããã®ã§ãNumPyã«æ
£ããŠããæ¹ãªãããã«äœ¿ãããªããå°è±¡ãããã
Daské åã§å¯Ÿå¿ããŠããªããã®ã®äŸ
-
äžéšãé€ããç·åœ¢ä»£æ°é¢ä¿ :
da.linalgé¢ä¿ã¯ãNumPyãšæ¯ã¹ããšå€ãã®ãã®ããµããŒããããŠããªãããããNumPyå éšã§äœ¿ãããŠããBLASãªã©ã®ã©ã€ãã©ãªã絡ãã§ãããŸããµããŒããããŠããªããšã®ããšã - sortãªã©ã®åŠç : èšå€§ãªããŒã¿ã§ã®ãã«ãœãŒããªã©ã¯å¶éãããã€ã€ããœãŒãåŸã®äžäœã®å€ãéšåçã«åã£ãããªã©ã¯ãµããŒããããŠããã
- tolistãªã©ã®é¢æ° : ããããèšå€§ãªããŒã¿ã§éçšã§Pythonã®é åã«å€æãããšã¡ã¢ãªãæ»ã«ãããªã®ã§äœ¿ããªãæ°ããããcompute颿°ã®åŸãNumPyé åãªã©ã«ãªãã®ã§ãå¿ èŠã§ããã°ãã¡ããã倿ããã°å€§äžå€«ããã§ã¯ããã
- ãã®ä»ã®ããŸã䜿ãããªããã€ããŒãªé¢æ°ãªã©
Daské åãšãã£ã³ã¯ãµã€ãºã®è©±
åè¿°ã®éããDaské
åã®å
éšã§ã¯ãã£ã³ã¯ãµã€ãºåäœã§ã®å€ãã®NumPyé
åã§æ§æãããŠããã
ãã®ãã£ã³ã¯ãµã€ãºãã©ã®ããã«èšå®ãããã«ãã£ãŠãããã©ãŒãã³ã¹ãå€ãã£ãŠãããããã®ã§ãé ã®çé
ã«å
¥ããŠãããšããªãã ãããã«é
ããã¿ãããªããšãé¿ããããšãã§ããã
åºæ¬çã«ãDaské
åã®çæåŠçãªã©ã®é¢æ°ã§ã¯ããã£ã³ã¯ãµã€ãºãæå®ããchunksãšããåŒæ°ã§ããã£ã³ã¯ãµã€ãºãæå®ããããšãã§ããããã£ã³ã¯æ°ã§ã¯ãªãã®ã§æ³šæïŒchunk shapeçãªæå³ã§ã®chunksãšããåŒæ°åã§ãããchunk_numçãªæå³ã§ã¯ãªãïŒã
ãã£ã³ã¯æ°ã1ã€ã ãã«ããããšèããŠãchunks=1ãªã©ãšæå®ãããšãã¹ã«ã©ãŒå€ããšã«ãã£ã³ã¯ãäœãããŠããªãŒããŒãããã§çžåœé ããªãã®ã§æ³šæã
ãªããããã©ã«ãå€ã§ã¯chunks='auto'ãšãªã£ãŠããã
DaskåŽã§ãããªã«æ±ºããŠãããã®ã§ã现ãããã¥ãŒãã³ã°ãé¢åã§ããã°autoãäºæ
ãã«ãããŠç¡é£ãããªå°è±¡ã¯ããŠããã
æåã§æå®ããå Žåã«ã¯ã以äžã®ãããªç¹ãåèã«ãããšè¯ãã
- ãã£ã³ã¯ãµã€ãºã¯å€§ããããŠãå°ããããŠãè¯ããªã : ããŒã¿éã«å¯ŸããŠå€§ãããããšã¡ã¢ãªãå€ãå¿ èŠã«ãªããå°ãããããšå€§éã®åå²ã«ããéœåã§ããªãŒããŒãããã§é床ãç ç²ã«ãªãã
-
ãã£ã³ã¯ãµã€ãºã¯åºæ¬çã«100MB以äžã®ã¡ã¢ãªãµã€ãºãç®å®ã«ãã : ãã以äžã«ãªããšãæ±ãããŒã¿ãµã€ãºã«ãã£ãŠã¯åå²ãå€ãããŠãªãŒããŒãããã倧ãããfloat64ãªã©ã®å€ã§ããã°å¿
èŠã¡ã¢ãªã8ãã€ããªã®ã§ãè¡åã§ããã°
(4000, 4000)ãããã®ãµã€ãºã§ã4000 * 4000 * 8 / 1000 / 1000 = 128MBãšãã£ãããã«100MBãè¶ ããŠããã -
ãã£ã³ã¯åäœã®ã¡ã¢ãª à 10 Ãã³ã¢æ°ã§èšç®ãããšãã«ãPCã®ã¡ã¢ãªãè¶
ããªãããã«ãã : åºæ¬çã«ç¬éçãªèšç®ã§ã¯ãã£ã³ã¯åäœã§æ±ããããã³ã¢ã®æ°ã ã䞊åã§ã¡ã¢ãªã«ç¢ºä¿ããããããã®ã§ããã£ã³ã¯åäœã®ã¡ã¢ãªé à ã³ã¢æ°ã®ã¡ã¢ãªãæäœéå¿
èŠã«ãªãããŸããå¹çåçã«èªã¿èŸŒã¿åŸ
ã¡ãªã©ãé¿ãããããDaskåŽã§è¿ããã¡ã«å¿
èŠã«ãªããã£ã³ã¯ãèšç®äžã«èªã¿èŸŒãã ããããããããã£ã³ã¯10ååãããã¯æå€§ã§ç¢ºä¿ãããå¯èœæ§ããããããïŒãããŸã§ã¯ã»ãŒããããšã¯ç¡ããšã¯æãããïŒããã®ãããããšãã°ãã£ã³ã¯åäœã§100MBã®ã¡ã¢ãªãµã€ãºã®ããŒã¿ã§ãã³ã¢ã4ã€ç©ãã§ãããã·ã³ã§èšç®ããå Žåã«ã¯ã
100 * 10 * 4 = 4000MBãšãªãã4GBãããã¯ãã·ã³ã«ã¡ã¢ãªãå¿ èŠã«ãªã£ãŠãããã¡ã¢ãª32GBã®ãã·ã³ã§ããã°ããã£ã³ã¯åäœã®ã¡ã¢ãªãµã€ãºã800MBããããŸã§ã¯ç¡é£ã«æ±ããããšã«ãªãã - ãã£ã³ã¯åå²ã«ãããªãŒããŒãããã«é æ ®ãã : ãã·ã³ã¹ããã¯ã«äŸåãããã®ã®ãäžã€ã®ãã£ã³ã¯ãèšç®ãªã©ã§æ±ãéã®ãªãŒããŒãããã1ããªç§çšåºŠããã£ãããããããã现ãããã£ã³ã¯ãåå²ãããããšãã®ãªãŒããŒããããçµæ§é¿ããŠããããŸãã§ããããšãã°float64ã®åã§500äžè¡10åã®ãµã€ãºã®è¡åã§ãã£ã³ã¯ãµã€ãºãèšå®ããïŒãã£ã³ã¯åäœã®ã¡ã¢ãª400MBãããïŒãšããŠãããã£ã³ã¯500åã§25åè¡ãšãã®èŠæš¡ãªã®ã§ã1ã€1ããªç§çšåºŠãªãå°ãåŸ ã£ããããŠããã°åå察å¿ã§ããããªæ°ãããŠããããããããã¯ããã«ããŒã¿ãµã€ãºã倧ãããªã£ãŠãããæµç³ã«åæ£ç°å¢ãªã©ã䜿ã£ãã»ããå¿«é©ãããªå°è±¡ã¯ããã
-
è¡åãªã©ãæ£æ¹è¡åã§ã¯ãªãå Žåã¯ãã®åœ¢ã«åããããã£ã³ã¯ãµã€ãºã«ãã : ããšãã°ã
(10000000, 10000)ãšãã£ããããªãµã€ãºã®è¡åãæ±ãå Žåã«ã¯ããã£ã³ã¯ãµã€ãºã®æ¹ããã¡ãã«åãããŠé·æ¹åœ¢ã§æå®ããã®ã奜ãŸããïŒ(1000000, 1000)ãšãã£ãå ·åã«ïŒã
ãã£ã³ã¯ãµã€ãºãšãã¡ã€ã«åäœ
ããå¯èœã§ããã°ãã£ã³ã¯ãµã€ãºåäœã§ãã¡ã€ã«ãåå²ãããŠãããšãèªã¿èŸŒã¿ã䞊åã§ã§ããŠäžã€ãã£ã³ã¯ã®èšå®ãã¹ã ãŒãºã§å¥œãŸãããããã
ãã£ã³ã¯ã®autoæã®æåãšæåã§ã®ãµã€ãºæå®æã®æå
ã©ã®ããã«ãã£ã³ã¯ãµã€ãºãæå®ãããŠãããã¯ãchunksize屿§ã§ç¢ºèªãã§ããã
arr = da.random.uniform(low=0.0, high=1.0, size=(10000000, 1000))
arr.chunksize
(16000, 1000)
chunksã®åŒæ°ãçç¥ããã®ã§ãããã©ã«ãã®chunks='auto'ã®
16000 * 1000 * 8 / 1000 / 1000 = 128MBãšãã£ãããã«ã100MBãè¶
ãããã£ã³ã¯ãµã€ãºã§èªåã§èšå®ãããŠããããšãåãããïŒäžã€ãè¡æ¹åã®æ¹ãé·ãè¡åãæå®ããã®ã§ããã£ã³ã¯ãµã€ãºãè¡æ¹åãé·ããµã€ãºã«ãªã£ãŠããã®ãåããïŒ
以äžã§ã¯ãäžèšã®ããã©ã«ãã®chunks='auto'ã§ã¯ãªãæåã§æå®ããéã®åå²ã®æåã«é¢ããŠèšèŒããŠããã
ãµã³ãã«ãšããŠã10 à 10ã®è¡åãå©çšããã
arr = da.arange(0, 100)
arr = arr.reshape((10, 10))
arr.compute()
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
[60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
[70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
[80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]])
- ã¹ã«ã©ãŒã®å€ãæå®ããå ŽåïŒ
chunks=5ãªã©ïŒãåæ¹åã«å¯ŸããŠãã®æ°ã§åå²ããããè¡åã§ããã°5 à 5ã®ãããã¯ã§åå²ãéæ°3ã®ãã³ãœã«ã§ããã°5 à 5 à 5ãšãã£ãæãã§åå²ãããã
èšå®åŸã®ãµã€ãºã¯chunks屿§ã§ç¢ºèªãã§ããã((è¡ã®åãã£ã³ã¯ã®ãµã€ãº), (åã®åãã£ã³ã¯ã®ãµã€ãº))ãšãã£ãããã«è¡šç€ºãããã
ãŸãããã£ã³ã¯ãµã€ãºãå調æŽããå Žåã«ã¯rechunk颿°ã䜿ãã
y = arr.rechunk(chunks=5)
y.chunks
((5, 5), (5, 5))
å¯èŠåãããšã以äžã®ããã«åå²ãããŠããã
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
[60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
[70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
[80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]]
- ã¿ãã«ãªã©ã§ãäŸãã°
(5, 2)ãšãã£ãããã«æå®ããå Žåãè¡æ¹åã»åæ¹å...ãšãã£ãæãã§ããã®åæ°åã§åå²ãããã
y = arr.rechunk(chunks=(5, 2))
y.chunks
((5, 5), (2, 2, 2, 2, 2))
åæ¹åã®ãµã€ãºãå°ããããã®ã§ãåæ¹åã5ã€ã«åå²ãããŠããããšãåããã
以äžã®ããã«åå²ãããŠããã
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
[60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
[70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
[80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]]
- ãã®ä»ã«ããchunksã«æå®ããã¿ãã«ã®æ¬¡å ãå¢ãããŠãåå¥ã«æå®ãããããªæ¹æ³ã䜿ããããã ããã»ãšãã©äœ¿ãããªããšã®ããšïŒç¢ºãã«ãããŸãã¡ãªãããæãã€ããªãã»ã»ïŒã
y = arr.rechunk(chunks=((2, 2, 3, 3), (3, 7)))
y.chunks
((2, 2, 3, 3), (3, 7))
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
[60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
[70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
[80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]]
åºæ¬çã«ã¯ã¹ã«ã©ãŒã§chunks=4000ãšãã£ãæå®ããã·ã³ãã«ãªã¿ãã«ã§chunks=(8000, 2000)ãšãã£ããããªæå®ãå€ãã®ã§ã¯ãšããå°è±¡ã
ãã£ã³ã¯ãµã€ãºã®åèšå®ïŒrechunk颿°ïŒã¯ãæ¯èŒçå¹ççã«åŠçãããããããããŸãé »ç¹ã«å®æœããã®ã埮åŠãããããªããšã¯æãäžæ¹ã§ãã¹ã©ã€ã¹ãªã©ã§ããŒã¿ã®ä»¶æ°ãçµæ§å€åãããã£ã³ã¯ã现ãããªã£ãŠããŸã£ãéãªã©ã«ã¯å調æŽããã»ããå¹ççã«èšç®ãè¡ãªããã±ãŒã¹ãåºãŠããã
èªåã®ãã£ã³ã¯ãµã€ãºèšå®ã®è£è¶³
-
chunks='auto'ãšãã£ãæå®ã®ä»ã«ãã¿ãã«ã§äžéšã®æ¬¡å ã ãautoãæå®ããããšãã§ããã
arr = da.random.uniform(size=(1000000, 1000), chunks=(20000, 'auto'))
ããšãã°ãäžèšã®ããã«è¡æ¹åã ãåºå®ã®ãã£ã³ã¯ãµã€ãºãæå®ããŠãåæ¹åã¯autoãšæå®ãããšãDaskåŽãåæ¹åã ãè¯ãæãã«ãµã€ãºãéžæããŠããããïŒNumPyã§ãããšããã®shape屿§çã«Daskã®ãã£ã³ã¯ãµã€ãºãèŠããå Žåã«ã¯chunksize屿§ã§ç¢ºèªãã§ãããïŒ
arr = da.random.uniform(size=(1000000, 1000), chunks=(20000, 'auto'))
arr.chunksize
(20000, 500)
- ãã£ã³ã¯ãµã€ãºã«
-1ãæå®ãããšããã®æ¬¡å ã¯ãã£ã³ã¯ã®å¶åŸ¡ãè¡ãªããªãïŒå šäœã®ããŒã¿ãå©çšããïŒããã«ããããšããæå®ã«ãªããNumPyã®reshapeãªã©ã ãšã-1ã®æå®ãDaskã®'auto'ã«è¿ãæåã«ãªãã®ã§æ³šæã
以äžã®ããã«ã-1ãæå®ããæ¬¡å
ã¯ããã®Daské
åã®ãµã€ãºãšåãå€ïŒããŒã¿å
šäœïŒã®ãã£ã³ã¯ãšãªãã
arr = da.random.uniform(size=(1000000, 1000), chunks=(20000, -1))
arr.chunksize
(20000, 1000)
- rechunkãªã©ã§ãã£ã³ã¯ãµã€ãºã調æŽããéã«ãäžéšã®æ¬¡å ã«Noneãæå®ãããšãNoneãæå®ãããŠããªã次å ã®ã¿å€æŽããããè¡æ¹åã¯ãã®ãŸãŸãåæ¹ååŽã ã倿Žããããšãã£ããšãã«äŸ¿å©ã
arr = da.random.uniform(size=(1000000, 1000), chunks=(50000, 500))
arr.chunksize
(50000, 500)
arr = arr.rechunk((None, 1000))
arr.chunksize
(50000, 1000)
-
'auto'ãæå®ããéã®ãµã€ãºäžéã¯ãdask.config.get('array.chunk-size')ã§ç¢ºèªãã§ããã
import dask
dask.config.get('array.chunk-size')
'128MiB'
ãã®èšäºãæžããŠããDaskã®ããŒãžã§ã³ã§ã¯ãããã©ã«ãã§ã¯128MBã«ãªã£ãŠããæš¡æ§ããã ããåè¿°ã®èšç®ã§å¿ èŠã¡ã¢ãªéãšPCã®ã¹ããã¯ãèãããšã128MBã ãšå°ãå°ããæ°ããããããŒãPCã§ã¡ã¢ãªãå°ãªãã±ãŒã¹ããCPUã®æ°ã®å²ãã«ã¡ã¢ãªãå°ãªãã±ãŒã¹ããããã¯ä»ã«ãè²ã ãªåŠçã§ã¡ã¢ãªã確ä¿ããªããã°ãããªããªã©ã®ã±ãŒã¹ãé€ããŠãã¡ã¢ãªèšå®ã倧ããããã»ããé床ã¯éããªãã®ã§ãå¿ èŠã«å¿ããŠèª¿æŽãè¡ãªãã
以äžã®ããã«ãconfigã®å€ã®å€æŽååŸã§ã'auto'æå®æã®ãã£ã³ã¯ãµã€ãºãå€ãã£ãŠããã
import dask
dask.config.get('array.chunk-size')
'128MiB'
arr = da.random.uniform(size=(1000000, 1000), chunks=(20000, 'auto'))
arr.chunksize
(20000, 500)
dask.config.set({'array.chunk-size': '256MiB'})
arr = da.random.uniform(size=(1000000, 1000), chunks=(20000, 'auto'))
arr.chunksize
(20000, 1000)
Daskã®ããŒã¿ãã¬ãŒã ããDaskã®é åã«å€æããéã®æ³šæç¹
- åºæ¬çã«Daskã®ããŒã¿ãã¬ãŒã ïŒåŸè¿°ïŒããé
åãžå€æããåŠçã¯ãPandasã®ãããªæèŠã§æ±ããã
to_dask_arrayã¡ãœãããPandasã®ããã«values屿§ã§ãã¢ã¯ã»ã¹ãã§ããã
import pandas as pd
import dask.dataframe as dd
df = pd.DataFrame(data=[{
'a': 1,
'b': 2,
}, {
'a': 3,
'b': 4,
}])
ddf = dd.from_pandas(data=df, npartitions=1)
arr = ddf.to_dask_array()
arr.compute()
array([[1, 2],
[3, 4]])
ãã ããDaskã®ããŒã¿ãã¬ãŒã ã¯Pandasã®ããŒã¿ãã¬ãŒã ãšç°ãªããããŒã¿ãå šãŠã¡ã¢ãªäžã«ã¯å±éããªãéœåããã®ãŸãŸã ãšãã£ã³ã¯ãµã€ãºã®è¡æ°ãæ¬ èœããïŒãã£ã³ã¯é¢ä¿ã®åŠçããããªãïŒããã®ãŸãŸã ãšãã¡ã¢ãªéãå€ãå¿ èŠã«ãªã£ãã䞊ååãªã©ã®é¢ã§é åã®èšç®ã奜ãŸãããªãã
arr.chunksize
(nan, 2)
ãããé¿ããã«ã¯ãto_dask_arrayãªã©ã®ã¡ãœããã®åŒæ°ã§lengths=Trueãšæå®ãããšãè¡æ°ãªã©ãã¡ãããšååŸããŠãé
åã®ãã£ã³ã¯ãµã€ãºã«èšå®ããŠãããããã«ãªãããã ããè¡æ°ç®åºã§å€æèªäœã¯èšç®ãèµ°ãã®ã§è² è·ã¯é«ãããããããé
åã倧ãããåŠçãå€ãã®ã§ããã°æããlengths=Trueããããã§ã¯ãªããŠé
åæäœãªã©ãã»ãšãã©ããªãã®ã§ããã°ããã©ã«ãã®ãŸãŸlengthsã®åŒæ°ãæå®ããªã圢ãããã®ã ãããã»ã»ãšããå°è±¡ã
arr = ddf.to_dask_array(lengths=True)
arr.chunksize
(2, 2)
äžéšãDaskã«scipyã®statsã¢ãžã¥ãŒã«ã®ã€ã³ã¿ãŒãã§ã€ã¹ããã
Daské
åã®äžã«ãdask.array.statsã¢ãžã¥ãŒã«ãšããŠãscipyã®ã€ã³ã¿ãŒãã§ã€ã¹ã®ãã®ãçšæãããŠãããscipyã®å
šãŠã¯ãªããã®ã®ãDaskã§ãã®ãŸãŸå©çšã§ããã®ã§ããããããã䟿å©ãªãšãããããããããªãã
DaskããŒã¿ãã¬ãŒã
Daskã®ããŒã¿ãã¬ãŒã ã¯ãDaské åãå€ãã®NumPyé åã§æ§æãããã®ãšåæ§ãå€ãã®Pandasã®ããŒã¿ãã¬ãŒã ã§æ§æãããã
Daské åã®æã¯åå²ã®åäœããã£ã³ã¯ãšåŒã°ããŠãããããã¡ãã¯ããŒãã£ã·ã§ã³ïŒpartitionïŒãšããåç§°ã§åå²åäœãåŒã°ããïŒåŒæ°åãªã©ãå«ãïŒã
â»Daské åã®ããã«åæ¹åã§ã®åå²ãªã©ã¯ã§ããªãã
ä»ã®Daskã®ã€ã³ã¿ãŒãã§ã€ã¹ãšåæ§ã«ãå¿ èŠãªèšç®ãæžããšã¿ã¹ã¯ã°ã©ããçæãããæåŸã«computeãèªãã§èšç®ãå®è¡ãããå®è¡åŸã¯Pandasã®ããŒã¿ãã¬ãŒã ãªã©ã§è¿åŽãããã
DaskããŒã¿ãã¬ãŒã ã§ã®ãã¡ã€ã«ã®èªã¿èŸŒã¿
Pandasã§è¯ã䜿ãread_csvãªã©ã®åèªã¿èŸŒã¿ã®é¢æ°ã¯Daskã§ãçšæãããŠããã
ãµã³ãã«ã³ãŒãçšãšããŠãæç³»åã®ããŒã¿ãæ³å®ããŠã以äžã®ããã«3ã€ã®ãã¡ã€ã«ãäºåã«çšæããã
import pandas as pd
import numpy as np
df_20190601 = pd.DataFrame(columns=['date', 'price'], index=np.arange(0, 1000000))
df_20190601.date = '2019-06-01'
df_20190601.price = np.random.randint(low=80, high=150, size=(1000000,))
df_20190602 = df_20190601.copy()
df_20190602.date = '2019-06-02'
df_20190602.price += 10
df_20190603 = df_20190602.copy()
df_20190603.date = '2019-06-03'
df_20190603.price += 10
df_20190601.to_csv('./2019-06-01.csv', index=False)
df_20190602.to_csv('./2019-06-02.csv', index=False)
df_20190603.to_csv('./2019-06-03.csv', index=False)
df_20190601.head(3)
| date | price | |
|---|---|---|
| 0 | 2019-06-01 | 139 |
| 1 | 2019-06-01 | 98 |
| 2 | 2019-06-01 | 127 |
- åäžã®ãã¡ã€ã«ã®èªã¿èŸŒã¿ã¯äœãèããªããŠããPandasæèŠã§è¡ãªããã
df = dd.read_csv('./2019-06-01.csv')
df.head(n=1)
| date | price | |
|---|---|---|
| 0 | 2019-06-01 | 139 |
- ç¹èšãã¹ãç¹ãšããŠãread_csvãªã©ã®èªã¿èŸŒã¿ç³»ã®é¢æ°ãã¢ã¹ã¿ãªã¹ã¯ã®è¡šèšã䜿ãããšã§ãè€æ°ãã¡ã€ã«ã«å¯Ÿå¿ããŠãããšããç¹ãäžãããããæåã«Daskã®ããŒã¿ãã¬ãŒã ãè§Šãå§ããéã«å€§åæåãããç¹æ®ãªæžãæ¹ãããªããŠãã䞊ååã®ã³ãŒããæžãããããªããŠããconcatãªã©ã®é¢æ°ãæãŸãªããŠããread_csvã®1è¡æžãã®ã¿ã§äžŠååãªã©ãŸã§ãã€ã€è€æ°ãã¡ã€ã«ã®èªã¿èŸŒã¿ãããããããã ãã§ããªãã ãDaskãåŠãã§ãè¯ãã£ããšæããïŒç§ã ãïŒïŒã
ããšãã°ãæç³»åã®CSVããããšããŠããã¡ã€ã«åã«%Y-%m-%dã®ãã©ãŒãããã§ä¿åãããŠãããšããã
ããå¯Ÿè±¡ã®æã®ããŒã¿ãäžæ¬ã§èªã¿èŸŒã¿ãããã°ã以äžã®ããã«æ¥ã®éšåãã¢ã¹ã¿ãªã¹ã¯ã«ãããšã該åœãããã¡ã€ã«ãå
šãŠèªã¿èŸŒãã§ããããconcatãªã©ãäžèŠã
df = dd.read_csv('./2019-06-*.csv')
df = df.compute()
len(df)
3000000
df.date.unique()
array(['2019-06-01', '2019-06-02', '2019-06-03'], dtype=object)
çšæããCSV3ã€åãå šãŠèªã¿èŸŒãŸããŠããããšãåããã
察象ã®å¹Žãæå®ãããå Žåã«ã¯ãæã®éšåãã¢ã¹ã¿ãªã¹ã¯ãæå®ãããšããã®å¹Žã®ãã¡ã€ã«ãå
šãŠèªã¿èŸŒãããšãã§ããã
ããšãã°ã2019幎ã®ãã¡ã€ã«ãå
šãŠèªã¿èŸŒã¿ããã®ã§ããã°ãdd.read_csv('./2019-*-*.csv')ãšããããã«æå®ããã
ãã®ãããªè€æ°ãã¡ã€ã«ã®ã¢ã¹ã¿ãªã¹ã¯ã®æå®ã¯ããã£ã¬ã¯ããªåãªã©ã§ãåäœããããã®ãããããšãã°S3ã«Hiveãã©ãŒãããã§CSVãªã©ãé 眮ããŠãããŠãåäžã®DWHã«ãã€ã€å¿ èŠãªã¿ã¹ã¯ã«å¿ããŠAthenaãDaskãªã©ã䜿ãåããããšãã£ãããšãéžæè¢ã«ã§ãããã§ã¯ãããïŒAthenaãBigQueryçã«äœ¿ãã€ã€ãè€éãªèšç®ãªã©ãgoofysãªããã§AWSã€ã³ã¹ã¿ã³ã¹ã«ããŠã³ãããŠãDaskã§æ±ã£ãããªã©ãïŒ
åè :
- Amazon Athenaã®ããŒãã£ã·ã§ã³ãçè§£ãã
- s3fsãããé«éã«äœ¿ããgoofysã詊ããŠã¿ã
Daskã®ããŒã¿ãã¬ãŒã ã§ãµããŒãããŠããŠãäžã€éãã€ã³ã¿ãŒãã§ã€ã¹ã®äŸ
-
èŠçŽ ããšïŒElement-wiseïŒã®æäœ : ããŒã¿ãã¬ãŒã å士ã®
+ã*ãªã©ã®èšç®ãªã©ã
df_1 = dd.from_pandas(pd.DataFrame(data=[{
'a': 100,
'b': 200,
}]), npartitions=1)
df_2 = dd.from_pandas(pd.DataFrame(data=[{
'a': 300,
'b': 400,
}]), npartitions=1)
df_3 = df_1 + df_2
df_3.compute()
| a | b | |
|---|---|---|
| 0 | 400 | 600 |
- ã¹ã©ã€ã¹é¢ä¿ :
df = dd.from_pandas(pd.DataFrame(data=[{
'a': 100,
'b': 200,
}, {
'a': 300,
'b': 400,
}]), npartitions=1)
df = df[df.a >= 200]
df.compute()
| a | b | |
|---|---|---|
| 1 | 300 | 400 |
- locã§ã®ã€ã³ããã¯ã¹ãçšããèŠçŽ ïŒãããã¯èŠçŽ ã®ç¯å²ïŒã®éžæ :
df = dd.from_pandas(pd.DataFrame(data=[{
'a': 100,
'b': 200,
}, {
'a': 300,
'b': 400,
}, {
'a': 500,
'b': 600,
}]), npartitions=1)
df = df.loc[1:2]
df.compute()
| a | b | |
|---|---|---|
| 1 | 300 | 400 |
| 2 | 500 | 600 |
- èŠçŽçµ±èšéãªã©ã®ç®åº : ããŒã¿ãã¬ãŒã å šäœã§ããè¡åäœãååäœïŒDask Series Structureãšãã衚瀺ããããã®ã§ãDaskã§ãã·ãªãŒãºãšåŒãã§åé¡ãªãããïŒã§ãåäœããã
df = dd.from_pandas(pd.DataFrame(data=[{
'a': 100,
'b': 200,
}, {
'a': 300,
'b': 400,
}]), npartitions=1)
sr = df.max()
sr.compute()
a 300
b 400
dtype: int64
- isinãªã©ã§ã®ããŒã¿ãã¬ãŒã ã¹ã©ã€ã¹åŠç :
df = dd.from_pandas(pd.DataFrame(data=[{
'a': 100,
'b': 200,
}, {
'a': 300,
'b': 400,
}, {
'a': 500,
'b': 600,
}]), npartitions=1)
df = df[df.a.isin([300, 500])]
df.compute()
| a | b | |
|---|---|---|
| 1 | 300 | 400 |
| 2 | 500 | 600 |
- groupbyãšããã®çµæã®èŠçŽçµ±èšéã®ç®åº :
df = dd.from_pandas(pd.DataFrame(data=[{
'a': 100,
'date': '2019-06-10',
}, {
'a': 300,
'date': '2019-06-10',
}, {
'a': 400,
'date': '2019-06-10',
}, {
'a': 500,
'date': '2019-06-11',
}]), npartitions=1)
grouped_df = df.groupby(by='date')
df = grouped_df.max()
df.compute()
| a | |
|---|---|
| date | |
| 2019-06-10 | 400 |
| 2019-06-11 | 500 |
â»groupbyããçµæã«å¯ŸããŠãapplyãªã©ãå®è¡ããå Žåã¯ã€ã³ããã¯ã¹ãäºåã«èšå®ããŠãããŠãgroupbyãªã©ã®å¯Ÿè±¡ã«ã€ã³ããã¯ã¹ãå«ããªããšé ããšããèšè¿°ãããã¥ã¡ã³ãã«ãããã€ã³ããã¯ã¹é¢ä¿ã¯ãPandasã®ãšããšæ¯ã¹ãŠããã©ãŒãã³ã¹ã«å€§ãã絡ãã§ããæš¡æ§ããã®ãããã®æèŠã¯PandasãšãŒã¡ãŒã¡ç°ãªãã®ã§æ³šæãMySQLãªããã®ã€ã³ããã¯ã¹äºã ã®è©±ã«è¿ãæèŠãåããã
- å€ã®ä»¶æ°ã®ã«ãŠã³ã :
df = dd.from_pandas(pd.DataFrame(data=[{
'a': 100,
}, {
'a': 300,
}, {
'a': 300,
}, {
'a': 500,
}]), npartitions=1)
sr = df.a.value_counts()
sr.compute()
300 2
500 1
100 1
Name: a, dtype: int64
- éè€åé€ :
df = dd.from_pandas(pd.DataFrame(data=[{
'a': 100,
}, {
'a': 300,
}, {
'a': 300,
}, {
'a': 500,
}]), npartitions=1)
df = df.drop_duplicates(subset=['a'], keep='first')
df.compute()
| a | |
|---|---|
| 0 | 100 |
| 1 | 300 |
| 3 | 500 |
-
ã€ã³ããã¯ã¹å士ã®é£çµ : â»ã€ã³ããã¯ã¹ãå©çšããªãé£çµã¯ããªãé
ããªããããã®ã§ãPandasã®æèŠã§mergeãªã©ãè¡ãªããšäžæ°ã«é
ããªãã±ãŒã¹ãããã®ã§æ³šæã
left_indexãšright_indexã«Trueãæå®ããããšãã£ãåŒæ°èšå®ããããšãé£çµæã«ã€ã³ããã¯ã¹ãå©çšããé£çµãšãªãããã ããã€ã³ããã¯ã¹ã®èšå®èªäœã¯é ãã®ã§ãæåã«1åã ãã€ã³ããã¯ã¹ãèšå®ãããªã©ããŠå¯Ÿå¿ããã®ã奜ãŸããããªããçåŽã®ããŒã¿ãã¬ãŒã ã®ã¿ã€ã³ããã¯ã¹ãåç §ã§ããå Žåã«ã¯ãã€ã³ããã¯ã¹ã®ããã©ãŒãã³ã¹æ¹åã®æ©æµãååã ã享åããããšãã§ããã
df_1 = dd.from_pandas(pd.DataFrame(data=[{
'id': 1,
'a': 100,
}, {
'id': 2,
'a': 300,
}]), npartitions=1)
df_2 = dd.from_pandas(pd.DataFrame(data=[{
'id': 1,
'b': 200,
}, {
'id': 2,
'b': 400,
}]), npartitions=1)
df_1 = df_1.set_index(other='id')
df_2 = df_2.set_index(other='id')
merged_df = dd.merge(
left=df_1, right=df_2,
left_index=True, right_index=True)
merged_df.compute()
| a | b | |
|---|---|---|
| id | ||
| 1 | 100 | 200 |
| 2 | 300 | 400 |
Daskã®ããŒã¿ãã¬ãŒã ã§ãµããŒãããŠãããã®ã®ãé ããã®
-
ã€ã³ããã¯ã¹ã®èšå® :
set_indexãªã©ã§è¡ãªããé »ç¹ã«ã€ã³ããã¯ã¹ãåèšå®ãããããã«ããªãã¹ãå°ãªãåæ°ïŒæåã®æ¹ã«1åã ãèšå®ããŠããã®åŸã¯ãã®ã€ã³ããã¯ã¹ã䜿ã£ãŠèšç®ããŠãããªã©ïŒã§æžãŸããã®ã奜ãŸããã
df = dd.from_pandas(pd.DataFrame(data=[{
'id': 1,
'a': 100,
}, {
'id': 2,
'a': 300,
}]), npartitions=1)
df = df.set_index(other='id')
- 1è¡1è¡æŽæ°ãè¡ãªãå¶åŸ¡ : ãã®èŸºãã¯Pandasã§ãé ãã£ããããããDaskã§ãåæ§ã«é ãã
- ã€ã³ããã¯ã¹ã䜿ããªãé£çµããgroupbyåŸã®ãªããžã§ã¯ãã®å€ãæŽæ°ãããããªåŠç
â»äžéšã®Pandasã®APIã¯ãµããŒãããããŠããªãïŒPandasåŽãã€ã³ã¿ãŒãã§ã€ã¹ãèšå€§ã«ããããïŒã察å¿ããŠãããã®ã¯ããã¥ã¡ã³ãã®APIã®ããŒãžã§ç¢ºèªã§ããïŒDaskåŽãèšå€§ã«ããã»ã»ã»ïŒã
Daskã®ããŒã¿ãã¬ãŒã ãèšç®éçšã§äžéšç¢ºèªãããå Žå
Daskã®ããŒã¿ãã¬ãŒã ã¯ãPandasã®ããŒã¿ãã¬ãŒã ãšç°ãªãã¡ã¢ãªã«éçšã§ããŒã¿ãèŒããªãäœãã«ãªã£ãŠããéœåãçŽæ¥ããŒã¿ã®ç¢ºèªãã§ããªãã以äžã®ããã«å€ã®éšåã...ãšãã衚èšã«ãªãã
df = dd.from_pandas(pd.DataFrame(data=[{
'id': 1,
'a': 100,
}, {
'id': 2,
'a': 300,
}]), npartitions=1)
df
éšåçã«éçšã®ããŒã¿ã確èªãããå Žåã«ã¯ãheadãtailãªã©ã®ã¡ãœããã§ããã°ãå 容ã®ç¢ºèªãå¹ãã®ã§ãã¡ãã䜿ãã
df.head(n=1)
df.tail(n=1)
ããŒã¿ãã¬ãŒã ã®ã€ã³ããã¯ã¹
åè¿°ããããã«ãmergeãgroupbyãªã©ã®å¶åŸ¡ã®éã«ãDaskã§ã¯Pandasã®æãããã€ã³ããã¯ã¹ãéèŠã«ãªã£ãŠãããïŒäžæ¹ã§ãã€ã³ããã¯ã¹ã®èšå®èªäœãé ããšãããžã¬ã³ãã¯ããã»ã»ã»ïŒ
1åã ãããã€ã³ããã¯ã¹ã䜿ãå¶åŸ¡ãããªããããªããã°ãset_indexãªã©ã§ã€ã³ããã¯ã¹ãèšå®ããã®ã¯ããŸãå¹ççã«ãªããªããããããªããäžæ¹ã§ãäœåºŠãã€ã³ããã¯ã¹ã䜿ããããããªã±ãŒã¹ã§ããã°ãäºåã«set_indexã§ã€ã³ããã¯ã¹ãèšå®ããŠãããã»ããããŒã¿ã«ã§ã¯æããéããªãã
ãŸããããšãã°ããŒã¿ãæ¥ä»ãªã©ã§åå²ãããŠããŠããããçµ±åããéã«ãDaskåŽã§èªåã§åããŒã¿ãããŒãã£ã·ã§ã³ãèšå®ãããããã€ã³ããã¯ã¹ã貌ãããšã§åããŒã¿ã®æ¥ä»ã®å¢çãªã©ãDaskåŽã§åããããã«ãªãããã®ãããªç¶æ
ã§ã¯ãããšãã°ã€ã³ããã¯ã¹ãåç
§ããæ¥ä»ã®ã¹ã©ã€ã¹ãªã©ãéåžžã«é«éã«åäœããããããã£ãåŠçãé«éã«åäœããç¶æ
ã«ãªã£ãŠãããã©ããã¯ãããŒã¿ãã¬ãŒã ã®known_divisions屿§ã§ç¢ºèªãã§ããã
df_1 = pd.DataFrame(columns=['date', 'a'], index=np.arange(0, 3000000))
df_1.date = '2019-06-10'
df_1.a = 100
df_2 = pd.DataFrame(columns=['date', 'a'], index=np.arange(0, 3000000))
df_2.date = '2019-06-11'
df_2.a = 200
df_3 = pd.DataFrame(columns=['date', 'a'], index=np.arange(0, 3000000))
df_3.date = '2019-06-12'
df_3.a = 300
df = dd.concat([df_1, df_2, df_3])
ãã®æç¹ã§ã¯ãŸã çµ±åã®ã¿ã§ãã€ã³ããã¯ã¹ã貌ã£ãŠããªãã®ã§known_divisionsã¯Falseã«ãªã£ãŠããã
df.known_divisions
False
ã€ã³ããã¯ã¹ã貌ããšknown_divisionsãTrueã«ãªãã
df = df.set_index(other='date')
df.known_divisions
True
ããŒã¿ãã¬ãŒã ã確èªãããšã以äžã®ãããªè¡šç€ºã«ãªããããŒãã£ã·ã§ã³ã®å¢çããœãŒããããŠããããšãåããïŒ2019-06-12ã2åããïŒãšãæã£ãããããã¥ã¡ã³ããèªãã§ããéã倧äžå€«ãããªå°è±¡ãããã®ã§ã¹ã«ãŒããïŒã
詊ãã«ã2019-06-10, 2019-06-12, 2019-06-11ãšããé çªã§ããŒã¿ãã¬ãŒã ãconcatããŠã¿ããšãããåè¿°ã®ã¹ã¯ã·ã§ã®12 tasksãšãªã£ãŠããç®æã®ã¿ã¹ã¯æ°ãå¢ãããããã¥ã¡ã³ãã«ãã€ã³ããã¯ã¹ã¯ãœãŒããããŠãããšã€ã³ããã¯ã¹ã®èšå®ãæ©ãçµãããšæžãããŠããã®ã§ãæãããœãŒãã®å¶åŸ¡ãå¢ããåèšç®ãé
ããªãã®ããªããšããå°è±¡ã
ããŒã¿ã®æå®é ãªã©ïŒå Žåã«ãã£ãŠã¯CSVãªã©ã§ä¿åæãªã©ã«ãããœãŒãããŠãããªã©ïŒã«ã¯æ°ãé
ã£ãã»ããè¯ãã±ãŒã¹ããããããããªãã
ããã«èšããšãäºåã«ãœãŒãã確å®ã«ãããŠããåæã§ãset_indexã¡ãœããã§sorted=TrueãåŒæ°ã«æå®ãããšã€ã³ããã¯ã¹ã®èšå®ãé«éã«ããããããã詊ãã«ãæ¥ä»ããœãŒããããŠããªãç¶æ
ã®set_indexãšãœãŒããããŠããç¶æ
ã§concatãããsorted=Trueãæå®ããŠã€ã³ããã¯ã¹ãèšå®ããéã®é床ã®å·®ã確èªããŠã¿ãïŒ300äžè¡ã®ããŒã¿ãã¬ãŒã à 3ïŒã
ãŸãã¯ãœãŒããããŠããªãæ¡ä»¶ããã
%%timeit
df = dd.concat([df_1, df_3, df_2])
df = df.set_index(other='date')
1 loop, best of 3: 5.49 s per loop
倧åé ãã
ç¶ããŠãœãŒããããŠããæ¡ä»¶ã
%%timeit
df = dd.concat([df_1, df_2, df_3])
df = df.set_index(other='date', sorted=True)
5å匱çšåºŠéããªã£ãã
ããŒãã£ã·ã§ã³ã®è©±
Daskã®ããŒã¿ãã¬ãŒã ã§ã¯ãæå®ãçç¥ããå Žåãªã©ã¯èªã¿èŸŒã¿ã§æå®ããããã¡ã€ã«æ°ããconcatãªã©ã§ããŒã¿ã®é£çµãããå Žåã¯ãã®åæ°ã«å¿ããããŒãã£ã·ã§ã³ãèªåã§èšå®ãããã
ãã ããDaské
åã®ãã£ã³ã¯ãµã€ãºãšåæ§ããã®ããŒãã£ã·ã§ã³ã®ãµã€ãºããå°ããããŠã倧ããããŠãããã©ãŒãã³ã¹é¢ã§å¥œãŸãããªããïŒå°ãããããšåå²ã«ãããªãŒããŒãããã倧ãããªãã倧ãããããšç¬éçã«ã¡ã¢ãªãå€ãå¿
èŠã«ãªã£ãŠããŸãïŒ
ããŒãã£ã·ã§ã³ãæ°äžãšãã«ãªã£ãŠããããªãŒããŒãããçã«å€§åãã€ããããããªãã
奜ãŸãããµã€ãºçã«ã¯ã倧äœãã£ã³ã¯ãµã€ãºã®ãšããšåããããªæèŠã§åé¡ã¯ãªãã䜿ããã·ã³ã®ã¡ã¢ãªãã³ã¢æ°ã«åãããŠã1ã€ã®ããŒãã£ã·ã§ã³ã§å€§äœ100MBïœæ°çŸMBçšåºŠã®ç¯å²ã«ãªãããã«ããŠãããšå¥œãŸããã
ããããã±ãŒã¹ã§ã¯ãèšç®ã®éäžã§ã¹ã©ã€ã¹ãªã©ãããŠãããŒã¿éã¯å°ãªããªã£ãŠããã«ãé¢ãããã倧éã®ããŒãã£ã·ã§ã³ã®ãŸãŸèšç®ãè²ã
ãã£ãŠããŸãã±ãŒã¹ããããã£ããéçšã§ããŒã¿ã倧åå°ãªããªãæ¡ä»¶ããããäžã€ãã®åŸãèšç®ãçµæ§ç¶ãå Žåã«ã¯äžæŠrepartitionãªã©ã®ã¡ãœããã§ããŒãã£ã·ã§ã³æ°ãæžãããŠãããšããã®åŸã®èšç®ãå¹ççã«å®è¡ãããã
ã¹ã©ã€ã¹ã§æžã£ãä»¶æ°ã«æ¯çã«å¿ããŠãããŒãã£ã·ã§ã³æ°ãæžã£ãæ¯çãå å³ããŠæžããèšå®ãããäŸ :
row_num = 10000000
df = pd.DataFrame(
columns=['a', 'b', 'c'],
index=np.arange(0, row_num))
df.a = np.random.randint(0, 100, size=(row_num,))
df.b = np.random.randint(0, 100, size=(row_num,))
df.c = np.random.randint(0, 100, size=(row_num,))
df = dd.from_pandas(data=df, npartitions=10)
before_row_num = len(df)
df = df[df.a >= 75]
after_row_num = len(df)
print('before_row_num:', before_row_num, ', after_row_num:', after_row_num)
before_row_num: 10000000 , after_row_num: 2500901
npartitions = int(df.npartitions / (before_row_num / after_row_num))
npartitions
2
df = df.repartition(npartitions=npartitions)
é£çµã®è©±
æ¢ã«ã€ã³ããã¯ã¹ãªã©ã®ç¯ã§ããçšåºŠè§ŠããŠãããmergeãªã©ã®é£çµé¢ä¿ã®æäœã«é¢ããŠãã€ã³ããã¯ã¹å士ã®é£çµä»¥å€ã§ã以äžã®ãããªã±ãŒã¹ã§ã¯éããªãã
- è€æ°ã®ããŒãã£ã·ã§ã³ãæã€ããŒã¿ãã¬ãŒã ãšã1ã€ã®ããŒãã£ã·ã§ã³ããæããªãããŒã¿ãã¬ãŒã ãé£çµããå Žå : è€æ°ã®ããŒãã£ã·ã§ã³ãæã€å€§ããªæ¢åã®ããŒã¿ãã¬ãŒã ã«å¯ŸããŠã1ã€ã®ããŒãã£ã·ã§ã³ããæããªãå°ããªããŒã¿ãã¬ãŒã ïŒè¿œå ã§å¿ èŠã«ãªã£ãŠèªã¿èŸŒãŸããããŒã¿ãã¬ãŒã ãªã©ïŒãé£çµããã±ãŒã¹ã¯éãåäœããã
- Daskã®ããŒã¿ãã¬ãŒã ãšPandasã®ããŒã¿ãã¬ãŒã ãé£çµããå Žå : ãã®ã±ãŒã¹ããå®è³ªPandasåŽã®ããŒã¿ãã¬ãŒã ãããŒãã£ã·ã§ã³ã1ã€ã®ããŒã¿ãã¬ãŒã ãšããŠæ±ããã®ã§éãåäœããã
äžèšã®ã±ãŒã¹ä»¥å€ã§ãäžã€ã€ã³ããã¯ã¹ãå å³ããªãé£çµã®å ŽåãããŒãã£ã·ã§ã³éã®ããŒã¿ã®ç§»åãæ€çŽ¢ãªã©ãè²ã å¿ èŠã«ãªããããåŠçãé ããªããïŒPandasãšç°ãªããDaskã®ããŒã¿ãã¬ãŒã ã¯è€æ°ã®ããŒãã£ã·ã§ã³ã§ããŒã¿ãåããããŠãããäžéšããã¡ã¢ãªäžã«å±éãããŠããªãã®ã§ãPandasã®æèŠã§æ±ããšãã£ãšé ããªãïŒ
locãšiloc
Pandasã§ã¯ç¹å®ã®äœçœ®ã®èŠçŽ ãåç
§ããéã«ãlocãilocãå¿
èŠã«ãªãã±ãŒã¹ããŒã¡ãŒã¡ããã
Daskã§ã¯ãlocã®æ¹ã¯åºæ¬çã«Pandasã®æèŠã§æ±ããã
ããšãã°ã以äžã®ãããªæžãæ¹ã¯ãµããŒããããŠããã
df.loc[0]
df.loc[1]
df.loc[:, ['id']]
äžæ¹ã§ãilocã®æ¹ã¯ãDaskãè¡æ°ãåžžã«ã¯ä¿æããŠããªããããç¹å®è¡ã®éžæã«ã¯äœ¿ããªãã£ãããããåçªå·ã®æå®ã«ã¯å¯Ÿå¿ããŠããã®ã§ãåºæ¬çã«è¡ã®æ¹ã¯ã³ãã³ã§å
šè¡æå®ããã圢ã§ããå©çšã§ããªãã
2çªç®ã®åã®ã¿ã®ããŒã¿ãã¬ãŒã ãååŸããäŸ :
df.iloc[:, [1]]
ãªããPandasã®å Žåã¯locãšç°ãªãilocã§ã®[è¡, å]ãšãã£ãéžæã¯ç¢ºãã§ããªãæ°ãããïŒiloc[è¡ã€ã³ããã¯ã¹][åå]ãªã©ãšæå®ããå¿
èŠãããïŒãã®ã®ãDaskã ãšåè¿°ã®ãããªæžãæ¹ãã§ããã
ilocã§ç¹å®è¡ã®éžæãããããšãããšãç¹å®è¡ã®éžæã«ã¯å¯Ÿå¿ããŠããªãã®ã§ã³ãã³ã§è¡å
šäœãéžæããŠãããšæãããã
df.iloc[0, [1]]
NotImplementedError: 'DataFrame.iloc' only supports selecting columns. It must be used like 'df.iloc[:, column_indexer]'.
ã¿ã¹ã¯ã°ã©ãã®å¯èŠå
åè¿°ããã¿ã¹ã¯ã°ã©ããå¯èŠåããæ©èœãDaskã«ã¯çšæãããŠããã
å©çšããã«ã¯ãgraphvizé¢ä¿ã®ã©ã€ãã©ãªãå¿
èŠã«ãªããpipãªã©ã ãšãgraphvizèªäœã®ã€ã³ã¹ããŒã«ãšPythonã®graphvizã©ã€ãã©ãªã®2ã€ãå¿
èŠã«ãªãã
Anacondaã®ã³ãã³ãã ãš1åã®ã³ãã³ãã§ãããªã«ã€ã³ã¹ããŒã«ããŠãããã
äŸåé¢ä¿ãšããè¥å¹²é¢åãªå°è±¡ãããã®ã§ãAnacondaã®ã³ãã³ãã®æ¹ã楜ãªå°è±¡ã¯ããã
$ conda install python-graphviz -y
The following NEW packages will be INSTALLED:
graphviz: 2.38.0-5
python-graphviz: 0.5.2-py36_0
å¯èŠåèªäœã¯visualizeã¡ãœããã§å®è¡ã§ãããããã¯computeã¡ãœããåæ§ãDaskã®åã€ã³ã¿ãŒãã§ã€ã¹å ±éã§çšæãããŠããã
import dask.array as da
x1 = da.random.uniform(low=0, high=1.0, size=(100, 100))
x2 = da.random.uniform(low=0, high=1.0, size=(100, 100))
x3 = da.random.uniform(low=0, high=1.0, size=(100, 100))
x4 = da.random.uniform(low=0, high=1.0, size=(100, 100))
y = x1 + x2 + x3 * x4
y.visualize()
ãã ããããŸãã«ããŒããå€ããã®ãªã©ã¯å¯èŠåã«ããªãæéãããã£ããã倱æãããããã®ã§æ³šæã
å¯èŠåã«é¢ããŠã¯ãå
容ã確èªã§ããã ãã§ãªããã±ãŒã¹ã«ãã£ãŠã¯é
ããªããããªç®æã®ç¹å®ã«ã圹ã«ç«ã€å Žåãããã
ããšãã°ãããŒãæ°ãçµ±åãããŠæžã£ãŠããç®æãããã°ã䞊åã§åŠçãããä»¶æ°ãæžã£ãããããããã®ããŒããçµãããŸã§çµ±åãã§ããªãã®ã§åŠçãåŸ
ã£ããããã
ãã®ãããããšãã°çåŽã ãæ¥µç«¯ã«é
ãããã®ããŒããçµ±åäºå®ã§ããã°ãçµ±åæã«ãã®ã¿ã¹ã¯æ¶ååŸ
ã¡ïŒããã«ããã¯ïŒãçºçãããããã
Dask Delayed
NumPyã€ã³ã¿ãŒãã§ã€ã¹ã®Daskã®é
åããPandasã€ã³ã¿ãŒãã§ã€ã¹ã®Daskã®ããŒã¿ãã¬ãŒã ã®ã»ãã«ãPythonèªäœã®ã³ãŒãã®ã€ã³ã¿ãŒãã§ã€ã¹ãšããŠäœ¿ããDelayedãšããã€ã³ã¿ãŒãã§ã€ã¹ãçšæãããŠããã
éåžžã®Pythonã³ãŒãã§å³æã§åŠçãèµ°ãã±ãŒã¹ãšã¯éããåŠçãé
å»¶è©äŸ¡ïŒä»ã®Daskã€ã³ã¿ãŒãã§ã€ã¹åæ§ã峿ã§ã¯èšç®ãèµ°ãããcomputeåŒã³åºãæç¹ã§èšç®ãªã©ãéå§ïŒããããããæãããããã£ãååãä»ããŠããã
Pythonãã«ãã€ã³ã®ãæ®éã®ãã«ãã¹ã¬ãããªã©ã®èšè¿°ãããèšè¿°ãã·ã³ãã«ã«æžããŠäžŠååãšã¿ã¹ã¯ã°ã©ãã®å©çšãªã©ãå®çŸã§ããã
äœ¿ãæ¹ã¯ãé
å»¶è©äŸ¡ãèšå®ããã颿°ãdask.delayed颿°ã§å²ããããã³ã¬ãŒã¿ãŒãå©çšããããšã§ã·ã³ãã«ã«æžãããšãã§ããã
-
delayed颿°ãæãäŸ :
dask.delayed(察象ã®é¢æ°)(颿°ã«èšå®ããåŒæ°)ãšãã£ãæžãæ¹ã«ãªãã
import dask
def increment(x):
return x + 1
def add(a, b):
return a + b
x = dask.delayed(increment)(5)
y = dask.delayed(increment)(10)
z = dask.delayed(add)(x, y)
dask.delayed(increment(5))ãšãã£ãæžãæ¹ãšééããªãããã«æ³šæãåŒæ°éšåã¯å€ã«åºããªããšé
å»¶è©äŸ¡ãããã«å³æã§èšç®ãèµ°ã£ãŠããŸãã
ãã®æç¹ã§ã¯ãŸã èšç®ãªã©ã¯èµ°ã£ãŠããªããzã®å
容ãèŠãŠãæ°å€ã®å
容ãªã©ã¯ç¢ºèªã§ããªãã
compute颿°ãåŒã³åºããæç¹ã§ã¯ãããŠåèšç®ãèµ°ãå§ããæ°å€ãååŸã§ããã
z.compute()
17
ãŸããDaské
åãªã©ã®ã€ã³ã¿ãŒãã§ã€ã¹ãšåæ§ããã¡ããã¿ã¹ã¯ã°ã©ãã®å¯èŠåãã§ããã
èªåã§èšç®ãæžã圢ã«ãªãã®ã§ãã°ã©ãå
容ãåãããããã
z.visualize()
-
ãã³ã¬ãŒã¿ãŒãä»ããŠå¯Ÿå¿ããå Žå :
@dask.delayedãšã¿ã¹ã¯ã°ã©ãã§æ±ããã颿°ã«èšå®ããããã¡ãã¯ããŒã¯ãŒãåŒæ°ãªã©ãåãä»ããŠãããïŒãã ãããã³ã¬ãŒã¿ãŒãä»ãããšåŒæ°ã*argsã**kwargsãšãã衚èšã«ãªã£ãŠå ¥åè£éãªã©ãå©ããªããªãïŒã®ãšãèšè¿°ãèªç¶ã§éåæããªãã
@dask.delayed
def increment(x):
return x + 1
@dask.delayed
def add(a, b):
return a + b
x = increment(x=5)
y = increment(x=10)
z = add(a=x, b=y)
z.compute()
17
ããã ãã§äžŠååãããã³ãŒãã«ãªãããšãŠãã·ã³ãã«ã
Pythonãã«ãã€ã³ã®äžŠååŠçã¢ãžã¥ãŒã«ã®å®å
šãªä»£æ¿ã«ã¯ãªããªãããã©ããDelayedã§å¿
èŠååãªéã«ããã£ãšäžŠååããããšããªã©äŸ¿å©ãªå°è±¡ã¯åããã
Daskã®é
åãDaskã®ããŒã¿ãã¬ãŒã ãèŠæãšãããPythonèªäœã®ã«ãŒããåããããªã©ã«ãåããŠããã
ãŸããPythonãã«ãã€ã³ã®é¢æ°ãªã©ã«å¯ŸããŠãdelayed颿°ãæãã§é
å»¶è©äŸ¡ã«ããããã§ããïŒäžèšã³ãŒãã®suméšåãªã©ãã»ãšãã©ã®Python颿°ããµããŒãããŠãããããïŒã
data_tuple = ((1, 2), (3, 4), (5, 6), (7, 8), (9, 10))
output_list = []
for x, y in data_tuple:
x = increment(x=x)
y = increment(x=y)
z = add(a=x, b=y)
output_list.append(z)
total = dask.delayed(sum)(output_list)
total.compute()
65
ã¿ã¹ã¯ã°ã©ãã衚瀺ããŠã¿ããšãã«ãŒãåããŒããå¢ããŠãã£ãŠããããšãåããã
ã©ããªãšãã«Daskã®Delayedã䜿ããã®äŸ
- Daskã®é
åãããŒã¿ãã¬ãŒã ã§çšæãããŠããAPIã ãã§ã¯è¶³ããªãã±ãŒã¹ãçºçããã«ãŒããåããããå¿
èŠã«ãªã£ãå Žåãéçšã§Delayedãçµç±ããå Žåã§ããé
åãããŒã¿ãã¬ãŒã ã®ã€ã³ã¹ã¿ãŒãã§ã€ã¹ã§
from_delayedãto_delayedãªã©ã®ã€ã³ã¿ãŒãã§ã€ã¹ãçšæãããŠãããçžäºã«å€æãã§ããã - Pythonã®ãã«ãã€ã³ã®äžŠååŠçã䜿ã£ãŠçްãã調æŽããããã»ã»ãäžèŠãªå Žåãåè¿°ã®éããã·ã³ãã«ãªèšè¿°ã§äžŠååŠçãªã©ãå®çŸã§ããã
è¯ããªãDelayedã®æžãæ¹
- computeã¯ãªãã¹ãå°ãªãæ°ãåŒã³åºã : ã§ããã°1åã«ãŸãšãŸãããã«ãããåæ°ãå€ããªããšãããããã®computeãçµãããªããšæ¬¡ã®èšç®ã«ç§»ããªããªãã䞊ååãããèšç®ã ãšãããããã«ããã¯ã«ãªã£ãããããmultiprocessingã¢ãžã¥ãŒã«ãªã©ã®joinãã«ãŒãå ã§åºæ¬æžããªãã®ãšåæ§ãã«ãŒãå ã§computeãåŒã³åºãããããªãããã«æ³šæã
- å ¥åå€ãçŽæ¥æŽæ°ããªã : åŒæ°ã«æž¡ãããå€ããã®ãŸãŸã€ã³ã¯ãªã¡ã³ãããããªã©ã¯å¥œãŸãããªãããããåäœã¯ããããšã¯ç¢ºèªããã䞊ååæã®ã¡ã¢ãªã®ããã¯ãªã©ã®éœåãªãã ãããã»ã»ïŒä»¥äžè¯ããªãã³ãŒãäŸã
@dask.delayed
def test_func(x):
x += 1
return x
x = test_func(x=1)
x.compute()
2
åè¿°ã®ãããªã³ãŒããå¿
èŠãªå Žåã«ã¯çŽæ¥ã€ã³ã¯ãªã¡ã³ãã§ã¯ãªãreturn x + 1ãšãã£ãå¥ã®å€æ°ã§æ±ãããåœ¢ã§æžãããcopyãªã©ãæããšãããããã
from copy import copy
@dask.delayed
def test_func(x):
x = copy(x)
x += 1
return x
x = test_func(x=1)
x.compute()
2
- ã°ããŒãã«å€æ°ãªã©ã«ã¯ã¢ã¯ã»ã¹ããªã : Daskã¯ãã«ãã¹ã¬ããããã«ãããã»ã¹ããããã¯åæ£ç°å¢ãªã©ã§æ±ãããããã«ãã¹ã¬ãã以å€ã§ã¯ã°ããŒãã«å€æ°ãªã©ã«ã¢ã¯ã»ã¹ããŠãããšåããªãã±ãŒã¹ãåºãŠããããã«ãã¹ã¬ããããå¥ã®ãã®ã«åãæ¿ããéã«èºãèŠå ã«ãªãã®ã§ãåºæ¬çã«ã°ããŒãã«å€æ°ãªã©ã«ã¢ã¯ã»ã¹ããŠããæžãæ¹ã¯å¥œãŸãããªãã以äžè¯ããªãæžãæ¹ã
global_list = []
@dask.delayed
def test_func(x):
global_list.append(x + 1)
x = test_func(x=1)
-
ã¿ã¹ã¯ãèšå€§ã«ãªãã±ãŒã¹ã¯é¿ãã : 现ãã颿°ã§èšå€§ã«Delayedãåæ ãããã®ãåŒã³åºããããããšã1ã€1ã€ã®Delayedã®ãªãŒããŒãããã¯äºçްã§ããå°å³ã«éŠ¬é¹¿ã«ãªããªããªãŒããŒãããã«ãªãããããã£ãå Žåã¯ããçšåºŠãŸãšãããããšããã¯è€æ°ã®é¢æ°ã®åŠçããŸãšããŠããªãŒããŒããããæžãããã«èª¿æŽãããããã«ãã€ã³ã®
multiprocessing.Poolãªã©ã®æ¹ãåããŠãããããããªãã -
Delayedã®æå®ãå ¥ãåã«ãªããããªæžãæ¹ã¯é¿ãã : ããšãã°ããã³ã¬ãŒã¿ãŒãã€ãããã颿°å ã§ããã«delayedãæãã§ä»ã®é¢æ°ãåŒã³åºããããªã©ãåºæ¬çã«ãããã£ãå ¥ãåã«ãªãäœ¿ãæ¹ã¯NGãšã®ããšã§ãã©ã¡ããã®ã¿ã«èšå®ãã圢ã«èª¿æŽããå¿ èŠãããã
-
Delayedæå®ããã颿°ã«ãçŽæ¥å€§ããªããŒã¿ã®åŒæ°ãäœåºŠãæå®ãã : ãããã£ãå Žåã¯ãå ã«ãã®ããŒã¿èªäœã«Delayedãæãã§ãããšå¥œãŸããïŒé¢æ°ä»¥å€ãDelayedãæãããšãã§ããïŒããããããšãããšãé¢ã§ãªãŒããŒããããå°ãªããªããããïŒæãããïŒã以äžå°ã倧ããã®é åã«å¯ŸããŠã
delayedãæãã§ã¿ãäŸã
large_arr = np.ones(shape=(100000,))
large_arr = dask.delayed(large_arr)
@dask.delayed
def sum_large_arr(large_arr):
return sum(large_arr)
output_list = []
for i in range(10):
x = sum_large_arr(large_arr=large_arr)
output_list.append(x)
total = dask.delayed(sum)(output_list)
total.compute()
1000000.0
ã¿ã¹ã¯ã°ã©ããå¯èŠåããŠã¿ãã
ã¹ã¿ãŒãã1ã€ã«ãªã£ãŠãããé
åã«delayedãæãã§ããã®ã§ãåããŒãã«æž¡ããããã®ãåäžã®ãã®ãåç
§ãããŠããããšãåãããæãã䞊ååæã«æž¡ãããŒã¿ã®ã³ããŒãªã©ã¯ããããåããã®ã䜿ããŸããããŠããã®ã§å¹ççã«åŠçãããã»ã»ã»ãšããããšãªã®ã ããããã¡ãªã¿ã«ãé
åã«delayedãæãŸãªããã®ã®ã¿ã¹ã¯ã°ã©ãã確èªãããšã以äžã®ããã«éå§ããŒãã1ã€ã«ãŸãšãŸã£ããã¯ããŠããªãã
ããã©ãŒãã³ã¹ãã¥ãŒãã³ã°
ãã®ãŸãŸã ãšãDaskã¯äžŠååŠçã忣åŠçã絡ãéœåã§ã颿°åäœã§ã®åŠçæéã®ãããã¡ã€ãªã³ã°çšã®%%prunã®ããžãã¯ã³ãã³ããããã®ã»ãã®ãããã¡ã€ãªã³ã°çšã®æ©èœãåããªãã£ããããã
ããã«èšããšããããã£ãèšæž¬ãå¿
èŠãªãšãã以å€ã«ãã䞊ååŠçã忣åŠçã«ããããŒã¿ã®å€æã®ãããšããããŒã¿è»¢éæéãã¿ã¹ã¯ã°ã©ãåã«ãããªãŒããŒããããªã©ãéåžžã®Pythonã§ã¯èšæž¬ãé£ããç®æãè²ã
ãšããã
ãã®ãããèšæž¬ãªã©ã«é¢ããŠã¯Daskèªäœã«ããçšåºŠçšæãããŠãããé ããªã£ãŠããç®æã®ç¹å®ãªã©ã«åœ¹ç«ãŠãããšãã§ããã
䞊åç°å¢ã®èšæž¬ã»èšºæ
忣ç°å¢ã ãšãŸã話ãå€ãã£ãŠãããšããããããã䞊åç°å¢ã§ããã°ä»¥äžã®ãããªæ©èœãçšæãããŠããïŒãã£ãã·ã¥åšããªã©äžéšå²æïŒã
ïŒæ¬èšäºã§ã¯å²æãããã®ã®ã忣ç°å¢ã§ããã°TensorBoardã¿ããwebããŒã¹ã§ç¢ºèªã§ããèšæž¬æ©èœãªã©ãããïŒ
- ããã°ã¬ã¹ã㌠: tqdmçãªè¡šç€ºããDaskã®äžŠååŠçç°å¢ã§å©çšã§ããã
- ã¿ã¹ã¯åäœã®ãããã¡ã€ã©ãŒ : ã¿ã¹ã¯åäœã§ã®åŠçæéã確èªã§ããã
- ãªãœãŒã¹ãããã¡ã€ã©ãŒ : ã¡ã¢ãªäœ¿çšéããCPU䜿çšçãªã©ã確èªã§ããã
ããã°ã¬ã¹ããŒ
䞊åç°å¢ã§ååŠçãå
šéšã§ã©ã®ãããé²ãã§ããã®ããtqdmçã«ç¢ºèªãã§ããã
dask.diagnostics.ProgressBarã¯ã©ã¹ã䜿ãã
䜿ãå Žåã«ã¯ãwithã¹ããŒãã¡ã³ãã§èšæž¬ãããcomputeã®ç®æã®ã¿å²ããããããã¯registerã¡ãœãããå©çšãããïŒåŸè ã¯ã³ãŒãå šäœã«åæ ãããïŒ
- withã¹ããŒãã¡ã³ãã§å²ãå Žå :
import dask.array as da
from dask.diagnostics import ProgressBar
arr = da.random.randint(low=0, high=100, size=(500000000,))
arr += 1
arr += 2
arr += 3
mean_val = arr.mean()
with ProgressBar():
result = mean_val.compute()
- registerã§ç»é²ããå Žå :
ãã¡ãã¯ã°ããŒãã«ã«åæ ããããwithã¹ããŒãã¡ã³ããªã©ã¯äžèŠã«ãªãã®ã§ãè€æ°åæã§äœåºŠãcomputeãåŒã¶å Žåãªã©ã§ã¯äŸ¿å©ã
éšåçã«èšæž¬ãããå Žåãªã©ã«ã¯æ³šæã衚瀺èªäœã¯withã¹ããŒãã¡ã³ãã䜿ã£ãéãšå€ãããªãã
progress_bar = ProgressBar()
progress_bar.register()
result = mean_val.compute()
ã¿ã¹ã¯åäœã®ãããã¡ã€ã©ãŒ
ãã¡ãã¯åã¿ã¹ã¯ã®éå§æéã»çµäºæéãªã©ã®èšæž¬ãšããŠäœ¿ããdask.diagnostics.Profilerã¯ã©ã¹ã䜿ãã
ããã°ã¬ã¹ããŒãšåæ§ã«ãwithã¹ããŒãã¡ã³ããregisterãªã©ã§å©çšã§ããã
Profilerã¯ã©ã¹ã®ãªããžã§ã¯ãã¯åŸã§å©çšããã®ã§ãäžæŠå€æ°ã«èšå®ããŠããã
from dask.diagnostics import Profiler
profiler = Profiler()
with profiler:
result = mean_val.compute()
èšæž¬çµæã¯ãããã¡ã€ã©ãŒãªããžã§ã¯ãã®results屿§ã«æ ŒçŽãããã
ãã ãããã®ãŸãŸç¢ºèªããŠããªãã ãã¿ã¹ã¯æ
å ±ãããããæ
å ±ãããã»ã»ã»ãšãããããããåãããªãã
profiler.results
[TaskData(key=('randint-mean_chunk-812e8f0cb4ac9321a67b998f47ae5f64', 0), task=(subgraph_callable, 3, 2, (<function _apply_random at 0x7fcf6a384598>, None, 'randint', array([1483484144, 3925864007, 3606941276, 3622924718, 2457601011,
2992342959, 3580848644, 3214909470, 229022156, 2784167203,
1520372, 1072208554, 870698918, 2640623133, 1663924999,
71001927, 3028677620, 1358626999, 3744700271, 2796033730,
2908454865, 4008216102, 728249598, 4040528145, 3680559835,
...
ãã®ãããåºæ¬çã«ã¯å¯èŠåããŠäœ¿ãããããã¡ã€ã©ãŒã«visualizeã¡ãœãããçšæãããŠããã®ã§ããã¡ãã䜿ãã
å
éšã§bokehã䜿ãããŠããã®ã§ãJupyteräžã§äœ¿ãå Žåã«ã¯ä»¥äžã®ãããªbokehã®èšè¿°ãããªããšè¡šç€ºããŠãããªãïŒ%matplotlib inlineçãªèšè¿°ãšæã£ãŠããã ããã°ïŒã
from bokeh.plotting import output_notebook
output_notebook()
BokehJS 0.12.5 successfully loaded.
瞊軞ãã¯ãŒã«ãŒããšïŒã³ã¢ã8åã®ãã·ã³ã§åãããŠããããã8åååå²ãããŠããïŒã暪軞ãçµéæéã§ãã¿ã¹ã¯ããšã«åè§ã®ãããã¯ã§è¡šç€ºãããŠããã
åãããã¯ã«ããŠã¹ãªãŒããŒãããšããã®ã¿ã¹ã¯ã®ããŒãçªå·ãç°¡åãªå
容ãªã©ãèŠãããã©ã®ã¿ã¹ã¯ãªã®ãã»ã»ãšããããšã¯æ£çŽåããã¥ããæããããïŒã¿ã¹ã¯ã°ã©ããäœããšãã«ååãšãä»ããããã®ã ãããã»ã»ïŒïŒ
ä»åã®ã±ãŒã¹ã§ã¯ãé»è²ã®è²ãä»ããŠãããããã¯ãåã¯ãŒã«ãŒã§åŠçãå®è¡äžãçœãé åããªãœãŒã¹ã空ããŠããç¶æ ïŒä»ã®ã¯ãŒã«ãŒã®åŠçåŸ ã¡ãªã©ïŒããšæãããïŒã¹ã¯ã·ã§ã®å³äžãèŠããšãè¥å¹²ã®çœããããã¯é åãããããšãåããïŒã
ä»åã®ãµã³ãã«ã³ãŒãã§ã¯ãæ£çŽå€§ããããã«ããã¯ã«ãªã£ãŠãããã®ãç¡ãããïŒã»ãšãã©å
šé¢ãé»è²ããªã£ãŠããïŒã§ã調æŽãäžèŠãããªããããçµæãšãªã£ãã
å
¬åŒã®ããã¥ã¡ã³ããèŠãŠãããšããã£ãšããã«ããã¯ãé¡èãªããããã«ãªã£ãŠããã®ã§ãæããã¢ã³ãã©ã³ã¹ãªè€éãªã¿ã¹ã¯ã«ãªã£ãŠããããã£ãšæçãªããããã«ãªãã®ã ããã»ã»ãšããå°è±¡ã
â»äžèšã®å³ã¯å ¬åŒã®ããã¥ã¡ã³ã Diagnostics (local)ããåŒçšã
ãªããregisterã§ã°ããŒãã«ã«ç»é²ããŠãããšãè€æ°ã®computeã§ã®èšç®ã®å
容ãããããã«å
¥ã£ãŠãããããŸãèŠããããšã¯èšããªãå°è±¡ãåããã®ã§ãå Žåã«ãã£ãŠã¯withã¹ããŒãã¡ã³ãã§åäœã®computeã®ã¿ã察象ã«ããã»ããèŠããããŠå¥œãŸãããããããªãïŒããã¯ãåŸè¿°ã®ãªãœãŒã¹ãããã¡ã€ã©ãŒã§ãåæ§ïŒã
ãªãœãŒã¹ãããã¡ã€ã©ãŒ
ãªãœãŒã¹ãããã¡ã€ã©ãŒã§ã¯ã䞊åç°å¢ã§ã®CPU䜿çšçãã¡ã¢ãªäœ¿çšéïŒMBåäœïŒã®ç¢ºèªãã§ããã
åºæ¬çãªäœ¿ãæ¹ã¯ã䜿ãã¯ã©ã¹ãResourceProfilerã¯ã©ã¹ã«ãªãã ãã§ãä»ã®ããã°ã¬ã¹ããŒããããã¡ã€ã©ãŒãšã»ãŒå€ããããwithã¹ããŒãã¡ã³ããregisterãªã©ã®ã¡ãœããã§ç»é²ããŠå©çšããã
from dask.diagnostics import ResourceProfiler
resource_profiler = ResourceProfiler()
with resource_profiler:
result = mean_val.compute()
results屿§ãèŠãŠã¿ããšãã¿ã¹ã¯ããšã®ãããã¡ã€ã©ãŒãšã¯ç°ãªãããã¡ãã¯ããããããªããŠãåååããå
容ãšãªã£ãŠããã
resource_profiler.results
[ResourceData(time=903533.34111646, mem=632.418304, cpu=0.0),
ResourceData(time=903534.38281667, mem=3682.156544, cpu=786.1999999999999),
ResourceData(time=903535.38432508, mem=2337.964032, cpu=779.7)]
ããã©ã«ãã§ã¯1ç§ããšã«èšæž¬ããããä»åã®èšç®ã¯2.5ç§ããã£ãã®ã§ã3ä»¶åèšæž¬ãããŠããã
æéã®æ
å ±ãšããã®ã¿ã€ãã³ã°ã®ã¡ã¢ãªäœ¿çšéã»CPU䜿çšéã確èªã§ãããCPUã¯ãKaggleã«ãŒãã«ã¿ããã«ãã³ã¢æ°Ã100ïŒ
ãMAXãšããŠè¡šç€ºãããã®ã§ãä»åã¯8åã®ã³ã¢ã®ãã·ã³ã§åãããŠããã®ã§ãå®å
šã«CPUãªãœãŒã¹ã䜿ãããŠããã°800ïŒ
ãšãªãïŒ780çšåºŠã®æ°åã«ãªã£ãŠããã®ã§ãã»ãšãã©ç¡é§ãªãCPUã䜿ã£ãŠããããšãåããïŒã
1ç§åŸãšã®èšæž¬ãã0.5ç§ããšã«ããŠãã£ãšçްããèšæž¬ãããïŒãããã¯ãã£ãšé·ãã¹ãã³ã§èšæž¬ãããïŒå Žåã«ã¯ãResourceProfilerã¯ã©ã¹ã®dtåŒæ°ã«ç§æ°ãæå®ãããšèª¿æŽãã§ããïŒdtã¯datetimeãªã©ã§ã¯ãªããdelta timeã ãšæãããïŒãããšãã°ã0.2ãæå®ããã°0.2ç§ééã§èšæž¬ãããå
ã»ã©ãŸã§ããã现ããèšæž¬ããããïŒçµæã®ããŒã¿ã®ä»¶æ°ãå¢ããïŒ
resource_profiler = ResourceProfiler(dt=0.2)
with resource_profiler:
result = mean_val.compute()
resource_profiler.results
[ResourceData(time=904075.205010556, mem=366.73536, cpu=0.0),
ResourceData(time=904075.445630621, mem=2024.218624, cpu=772.9),
ResourceData(time=904075.646472633, mem=3496.87808, cpu=790.6),
ResourceData(time=904075.847534518, mem=662.540288, cpu=781.8),
ResourceData(time=904076.048325532, mem=2146.500608, cpu=795.9),
ResourceData(time=904076.249606525, mem=3610.038272, cpu=790.3),
ResourceData(time=904076.450497805, mem=754.847744, cpu=772.3),
ResourceData(time=904076.651280945, mem=2326.319104, cpu=796.0),
ResourceData(time=904076.852340879, mem=3300.59776, cpu=785.7),
ResourceData(time=904077.05340738, mem=1114.50112, cpu=781.8),
ResourceData(time=904077.254200403, mem=2304.077824, cpu=731.4),
ResourceData(time=904077.455156886, mem=1699.852288, cpu=617.8)]
å ã»ã©ãããçµæã®ä»¶æ°ãå€ãããšãåããããŸããã¿ã¹ã¯åäœã®ãããã¡ã€ã©ãŒã§ãæåŸã®ã»ãã埮åŠã«ç©ºããŠããã¯ãŒã«ãŒããã£ããšããç¹ããåããããã«ããã¡ãã§ãæåŸã®æ¹ã®èšæž¬ã埮åŠã«ãªãœãŒã¹ã空ããŠããããšãåããã
ãã¡ããåæ§ã«ãvisualizeã¡ãœããã§ããããã衚瀺ããããšãã§ããã
resource_profiler.visualize()
玫ãCPU䜿çšçãéç·ãã¡ã¢ãªäœ¿çšéã
CPUã¯ã»ãšãã©ãã«ã«äœ¿ãããŠãããã¡ã¢ãªã®ã»ãã¯ã¿ã¹ã¯ããšã«å¿
èŠãªãšããã ã確ä¿ããŠã次ã®ã¿ã¹ã¯ã§äžèŠã«ãªã£ããšãããç Žæ£ããŠã»ã»ãšãã£ãŠããéœåãå±±ããè°·ãããªçµæã«ãªã£ãŠããã
éåžžã®ãããã°ãèšæž¬ã®ããŒã«ã䜿ãããå Žå
éåžžã¯ãDaskã§äžŠååãããŠããŠãããšã©ãŒãªã©ãã¡ãããšæ€ç¥ã§ããããèšæž¬çšã®æ©èœãçšæãããŠããã®ã§Daskã ãã§ããªããšããªã£ããããã
ããããDask以å€ã®%pdbã ã£ããã%debugã®ãããã°ã®ããžãã¯ã³ãã³ãã ã£ããã%prunãªã©ãå©çšããããããããªãã±ãŒã¹ãããïŒDaskåŽã§äžŠååã忣åŠçãªã©ãããéœåãéåžžã¯ãããã¯äœ¿ããªãïŒã
ãããã£ãå Žåã«ã¯ãDaskã®ã¹ã±ãžã¥ãŒã©ãŒïŒäžŠè¡åŠçã»äžŠååŠçã»åæ£åŠçãªã©ã®èšç®æ¹åŒçãªãã®ã®éžæïŒãã1ã€ã®ã¹ã¬ããã®ãã®ã«äžæçã«èšå®ããããšã§ã䞊ååãªã©ãäžéãç¡å¹åãããåè¿°ã®ããžãã¯ã³ãã³ããå©çšã§ããããã«ãªãã
䞊ååããããªããªãã®ã§ããã¡ããé ããªããã®ã®ããããã°ãªã©ã®é¢ã§å¿ èŠã«ãªã£ãå Žåã«å©çšããããšãã§ãããïŒãããã°ãªã©ãçµãã£ããæå®ãæ¶ããŠå ã«æ»ããããªã©ãè¡ãïŒ
computeã¡ãœããã®schedulerã®åŒæ°ã«'single-threaded'ãšæå®ãããšãåäžã®ã¹ã¬ããã§å®è¡ãããããã«ãªãã
resource_profiler = ResourceProfiler()
with resource_profiler:
result = mean_val.compute(scheduler='single-threaded')
resource_profiler.visualize()
[########################################] | 100% Completed | 5.2s
å
ã»ã©ã¯2ç§å°ã§çµãã£ãŠããã®ã§ã䞊ååããããªããªã£ãã®ã§é
ããªã£ãããšãåããããŸããCPU䜿çšçã®æå€§ã100ïŒ
ã«ãªã£ãŠããããšãåããã
ããšã¯ãå¿
èŠãªããžãã¯ã³ãã³ããæãã°ãéåžžã®Pythonã³ãŒãã®ããã«èª¿æ»ãã§ããã
ä»ã«ãPythonãªã©ãäžå¿ã«è²ã
èšäºãæžããŠããŸãããã¡ããã©ããïŒ
ä»ãŸã§ã«æçš¿ããäž»ãªèšäºãã¡
åèæç®ãŸãšã
- Daskå ¬åŒ ãããããŒãž
- Dask
- Install Dask
- Use Cases
- Why Dask?
- User Interfaces
- Array
- Best Practices (Array)
- Chunks
- Internal Design (Array)
- Stats
- Slicing
- Stack, Concatenate, and Block
- Bag
- DataFrame
- Best Practices (DataFrame)
- Joins
- Internal Design (DataFrame)
- Shuffling for GroupBy and Join
- Indexing into Dask DataFrames
- Delayed
- Best Practices (Delayed)
- Working with Collections
- Best Practices (Daskå šäœ)
- Scheduling
- Visualize task graphs
- Diagnostics (local)
- Debugging
- Amazon Athenaã®ããŒãã£ã·ã§ã³ãçè§£ãã
- s3fsãããé«éã«äœ¿ããgoofysã詊ããŠã¿ã




















