NumPy ã®é
åã«ã¯ãããã¼ããã£ã¹ãã£ã³ã°ã¨ããä»çµã¿ãããã¾ããããã¯ã大ããã®ç°ãªãå¤æ¬¡å
é
åå士ã®ç®è¡æ¼ç®ã«é¢ããä»çµã¿ã§ãè¦ç´ æ°ã 1 ã®æ¬¡å
ããã£ãå ´åã«ãããæ¡å¼µããäºã¤ã®é
åã®è¦ç´ æ°ãæãã¦æ¼ç®çµæãå¾ãã¨ãããã®ã§ããNumPy ã®ããã¥ã¢ã«ã§ã¯ã以ä¸ã®ãã¼ã¸ã«è¨è¼ãããã¾ããã¾ãããã®ãã¼ã¸ã®æ«å°¾ãããªã³ã¯ããã¦ãã EricsBroadcastingDoc ã«ã¯å
·ä½ä¾ãã¨ããªã説æãããã¾ãã
Broadcasting — NumPy v1.9 Manual
ãã®ããã¼ããã£ã¹ãã£ã³ã°ã PHP ã§å®è£ ãã¦ã¿ã¾ãããã³ã¼ãã¯ä»¥ä¸ã®ã¨ããã§ããé¢æ°åã® bsxfun 㯠Binary Singleton eXpansion FUNction ã®ç¥ã§ããããã¼ããã£ã¹ãã£ã³ã°ç¸å½ã®æ©è½ã¯ãMATLAB ã§ã¯ bsxfun é¢æ°ã§æä¾ããã¦ãããä»åã¯ãã®é¢æ°åã使ãã¾ããã
<?php function bsxfun($f, $a, $b) { $da = depth($a); $db = depth($b); $a = newAxis($a, $db - $da); $b = newAxis($b, $da - $db); return bsxfunRec($f, $a, $b); } function depth($a) { return is_array($a) ? depth($a[0]) + 1 : 0; } function newAxis($a, $n) { for ($i = 0; $i < $n; ++$i) { $a = array($a); } return $a; } function bsxfunRec($f, $a, $b) { if (!is_array($a)) { return $f($a, $b); } $a = expandIfSingleton($a, count($b)); $b = expandIfSingleton($b, count($a)); return array_map( function ($a, $b) use ($f) { return bsxfunRec($f, $a, $b); }, $a, $b); } function expandIfSingleton($a, $n) { if (count($a) == 1) { return array_fill(0, $n, $a[0]); } return $a; }
ç°¡åãªãã¹ãããã°ã©ã ã§ã®å®è¡ä¾ã¯æ¬¡ã®ã¨ããã§ãã$a 㯠1 è¡ 3 åã®è¡åã$b 㯠3 è¡ 1 åã®è¡åã表ãã¦ãã¾ãããããã®é åã«å¯¾ã㦠bsxfun é¢æ°ã§è¦ç´ ãã¨ã®ç©ãæ±ããã¨ã3 è¡ 3 åã®è¡åãå¾ããã¾ãã
$ cat bsxfun_test.php <?php require 'bsxfun.php'; $a = [1, 2, 3]; $b = [[1], [2], [3]]; $c = bsxfun(function ($a, $b) { return $a * $b; }, $a, $b); echo json_encode($c) . "\n"; $ php bsxfun_test.php [[1,2,3],[2,4,6],[3,6,9]]
å®è£ ãã bsxfun é¢æ°ã¯ãã¾ããå¼æ°ã®äºã¤ã®é åã®æ¬¡å æ°ãããããè¨ç®ã (depth é¢æ°)ã次å æ°ãç°ãªãå ´åã«ã¯ã次å æ°ã®å°ããªå´ãé åã§å ãã§ãããã¨ã§ã両è ã®æ¬¡å æ°ãæãã¾ã (newAxis é¢æ°)ããã®å¦çã¯ãNumPy ã®ããã¥ã¢ã«ã®ä»¥ä¸ã®è¨è¿°ã«å¯¾å¿ãã¾ãããã®ä¾ã§ã¯ãä¸æ¬¡å é åã® Scale ã 1x1x3 ã®ä¸æ¬¡å é åã«å¤æãã¦ããå¾ç¶ã®å¦çãè¡ãããã«ãã¾ã*1ã
Arrays do not need to have the same number of dimensions. For example, if you have a 256x256x3 array of RGB values, and you want to scale each color in the image by a different value, you can multiply the image by a one-dimensional array with 3 values. Lining up the sizes of the trailing axes of these arrays according to the broadcast rules, shows that they are compatible:
Image (3d array): 256 x 256 x 3 Scale (1d array): 3 Result (3d array): 256 x 256 x 3
bsxfunRec é¢æ°ã§ã¯ãè¦ç´ æ°ã 1 ã®æ¬¡å ãæ¡å¼µããªãã (expandIfSingleton é¢æ°)*2ãå帰å¼ã³åºãã«ãã£ã¦åè¦ç´ ã« $f ãé©ç¨ãã¾ãããã®é¨åã¯ãããã¥ã¢ã«ã®ä»¥ä¸ã®è¨è¿°ã«å¯¾å¿ãã¾ãã
When either of the dimensions compared is one, the other is used. In other words, dimensions with size 1 are stretched or âcopiedâ to match the other.
In the following example, both the A and B arrays have axes with length one that are expanded to a larger size during the broadcast operation:A (4d array): 8 x 1 x 6 x 1 B (3d array): 7 x 1 x 5 Result (4d array): 8 x 7 x 6 x 5
ãªããä»åã®å®è£ ã§ã¯ãå ¥åã®é åãããã¼ããã£ã¹ãã£ã³ã°ã®æ¡ä»¶ãæºãããªãå ´åãèæ ®ãã¦ãã¾ãããããã¯äºã¤ã®å ´åãããã¾ããä¸ã¤ã¯ã両è ã®è¦ç´ æ°ãã©ã¡ãã 2 以ä¸ã§ããã¤ãç°ãªã£ã¦ããå ´åã§ããNumPy ã®ããã¼ããã£ã¹ãã£ã³ã°ã§ã¯ããã®ãããªå ´åã«ã¯ã¨ã©ã¼ã«ãªãã¨å®ãããã¦ãã¾ããããä¸ã¤ã¯ãã¸ã£ã°é åãä¸ããããå ´åã§ããNumPy ã§ã¯ãç©å½¢é åã®å ´åã«éãããã¼ããã£ã¹ãã£ã³ã°ãé©ç¨ãããããã§ã*3ã
*1:ä»åã®ç§ã®å®è£ ã§ã¯ãããã§å®éã«é åãä½æãã¦æ¬¡å æ°ãæãã¦ãã¾ãããæ¬æ¥ããããå¿ è¦ã¯ããã¾ãããå復å¦çã§å®è£ ãããã¨ãã§ãã¾ãã
*2:ãã¡ãã array_fill ã§è¦ç´ æ°ãæããé åãå®éã«ä½æãã¦ãã¾ãããæ¬æ¥ãã®å¿ è¦ã¯ããã¾ããã
*3:ç§ã¯ Python ã NumPy ã«ã¯å ¨ã詳ãããªãã®ã§ãããNumPy ã® array ã§ã¯ãã¸ã£ã°é å㯠dtype=object ã¨ãªããç©å½¢é åã¨ã¯ç°ãªãå é¨æ§é ãæã¤ããã§ãã