【NumPy】ndarrayの形状を変えるresizeとreshape、そしてsplitの違い[Python]

  • URLをコピーしました!
目次

NumPy

前回、matplotlibでグラフの表示範囲の上限値、もしくは下限値だけ設定する方法を紹介しました。

今回はNumPyでndarrayの形状を変えるresizeとreshape、そしてsplitの違いを紹介します。

それでは始めていきましょう。

1次元から2次元への変更

まずは1次元ndarrayから2次元ndarrayの変更を見てみましょう。

resizeの場合

resizeの場合、「ndarray.resize([行の数, 列の数])」で2次元ndarrayに変更できます。

import numpy as np

data = np.arange(100)

data.resize([5,20])

print(data)

実行結果
[[ 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]]

resizeでは与えられたndarrayが変換されますので、変数に格納しようとしても何も格納されません。

import numpy as np

data = np.arange(100)

data_new = data.resize([5,20])

print(data_new)

実行結果
None

指定した分割数が元のndarrayの要素数よりも少ない場合、オーバーした分の要素は切り捨てられます。

import numpy as np

data = np.arange(100)

data.resize([5,15])

print(data)

実行結果
[[ 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]]

また指定した分割数が元のndarrayの要素数よりも多い場合、足りない分の要素は0で埋められます。

import numpy as np

data = np.arange(100)

data.resize([5,23])

print(data)

実行結果
[[ 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  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]]

reshapeの場合

reshapeの使い方は「ndarray.reshape([行の数, 列の数])」です。

import numpy as np

data = np.arange(100)

data_new = data.reshape([5,20])

print(data_new)

実行結果
[[ 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]]

reshapeでは元のndarrayは変更されず、新たなndarrayが作成されるので、変数に格納して使います。

また指定した分割数が元のndarrayの要素数と合わない場合、エラーとなります。

多くても少なくてもダメです。

import numpy as np

data = np.arange(100)

data_new = data.reshape([5,15])

print(data_new)

実行結果
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[7], line 5
      1 import numpy as np
      3 data = np.arange(100)
----> 5 data_new = data.reshape([5,15])
      7 print(data_new)

ValueError: cannot reshape array of size 100 into shape (5,15)
import numpy as np

data = np.arange(100)

data_new = data.reshape([5,23])

print(data_new)

実行結果
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[8], line 5
      1 import numpy as np
      3 data = np.arange(100)
----> 5 data_new = data.reshape([5,23])
      7 print(data_new)

ValueError: cannot reshape array of size 100 into shape (5,23)

splitの場合

splitは「np.split(ndarray, 分割数)」とします。

resizeやreshapeとは違い、今のndarrayを何分割するかを指定します。

そのため上記の例と同じ形状にするには行の数を分割数とします。

import numpy as np

data = np.arange(100)

data_new1 = np.split(data, 5)

print(data_new1)

実行結果
[array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19]), array([20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
       37, 38, 39]), array([40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
       57, 58, 59]), array([60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
       77, 78, 79]), array([80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
       97, 98, 99])]

splitも元のndarrayは変更されず、新たなndarrayが作成されるので、変数に格納して使います。

また分割できない場合、つまり余りが出てしまう場合はエラーとなります。

import numpy as np

data = np.arange(100)

data_new1 = np.split(data, 15)

print(data_new1)

実行結果
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[9], line 5
      1 import numpy as np
      3 data = np.arange(100)
----> 5 data_new1 = np.split(data, 15)
      7 print(data_new1)

File ~/.pyenv/versions/3.13.0/lib/python3.13/site-packages/numpy/lib/_shape_base_impl.py:889, in split(ary, indices_or_sections, axis)
    887     N = ary.shape[axis]
    888     if N % sections:
--> 889         raise ValueError(
    890             'array split does not result in an equal division') from None
    891 return array_split(ary, indices_or_sections, axis)

ValueError: array split does not result in an equal division
import numpy as np

data = np.arange(100)

data_new1 = np.split(data, 23)

print(data_new1)

実行結果
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[12], line 5
      1 import numpy as np
      3 data = np.arange(100)
----> 5 data_new1 = np.split(data, 23)
      7 print(data_new1)

File ~/.pyenv/versions/3.13.0/lib/python3.13/site-packages/numpy/lib/_shape_base_impl.py:889, in split(ary, indices_or_sections, axis)
    887     N = ary.shape[axis]
    888     if N % sections:
--> 889         raise ValueError(
    890             'array split does not result in an equal division') from None
    891 return array_split(ary, indices_or_sections, axis)

ValueError: array split does not result in an equal division

1次元から3次元への変更

resizeの場合

resizeを使って1次元ndarrayを3次元ndarrayに変更する場合は「ndarray.resize([a, b, c])」とします。

a, b, cはインデックスで要素を呼び出す順番と同じです。

import numpy as np

data = np.arange(120)

data.resize([5, 4, 6])

print(data)

実行結果
[[[  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 100 101]
  [102 103 104 105 106 107]
  [108 109 110 111 112 113]
  [114 115 116 117 118 119]]]

reshapeの場合

reshapeを使って1次元ndarrayを3次元ndarrayに変更する場合は「ndarray.reshape([a, b, c])」とします。

a, b, cはインデックスで要素を呼び出す順番と同じです。

import numpy as np

data = np.arange(120)

data_new = data.reshape([5, 4, 6])

print(data_new)

実行結果
[[[  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 100 101]
  [102 103 104 105 106 107]
  [108 109 110 111 112 113]
  [114 115 116 117 118 119]]]

splitの場合

splitはndarrayを分割する関数なので、3次元以上のndarrayを作成するには複数回splitする必要があります。

またその際、より細かい分割となる部分から分割していく必要があります。

例えば上記の120個の要素のndarrayを[5, 4, 6]という3次元ndarrayにする場合、120個の要素を6個ずつになるように分割します。

その際分割数は前の2つ(つまり5と4)の掛け算で計算できます。

import numpy as np

data = np.arange(120)

data_new1 = np.split(data, 5 * 4)
print(data_new1)

実行結果
[array([0, 1, 2, 3, 4, 5]),
 array([ 6,  7,  8,  9, 10, 11]), 
 array([12, 13, 14, 15, 16, 17]), 
 array([18, 19, 20, 21, 22, 23]), 
 array([24, 25, 26, 27, 28, 29]),
 array([30, 31, 32, 33, 34, 35]),
 array([36, 37, 38, 39, 40, 41]),
 array([42, 43, 44, 45, 46, 47]),
 array([48, 49, 50, 51, 52, 53]),
 array([54, 55, 56, 57, 58, 59]),
 array([60, 61, 62, 63, 64, 65]),
 array([66, 67, 68, 69, 70, 71]),
 array([72, 73, 74, 75, 76, 77]),
 array([78, 79, 80, 81, 82, 83]),
 array([84, 85, 86, 87, 88, 89]),
 array([90, 91, 92, 93, 94, 95]),
 array([ 96,  97,  98,  99, 100, 101]),
 array([102, 103, 104, 105, 106, 107]),
 array([108, 109, 110, 111, 112, 113]),
 array([114, 115, 116, 117, 118, 119])]

そしてこのndarrayをさらに4個ずつになるように分割します。

その時の分割数が[5, 4, 6]の最初の値、5です。

import numpy as np

data = np.arange(120)

data_new1 = np.split(data, 5 * 4)

data_new2 = np.split(np.array(data_new1), 5)

print(data_new2)

実行結果
[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]]), 
 array([[24, 25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34, 35],
       [36, 37, 38, 39, 40, 41],
       [42, 43, 44, 45, 46, 47]]),
 array([[48, 49, 50, 51, 52, 53],
       [54, 55, 56, 57, 58, 59],
       [60, 61, 62, 63, 64, 65],
       [66, 67, 68, 69, 70, 71]]), 
  array([[72, 73, 74, 75, 76, 77],
       [78, 79, 80, 81, 82, 83],
       [84, 85, 86, 87, 88, 89],
       [90, 91, 92, 93, 94, 95]]), 
  array([[ 96,  97,  98,  99, 100, 101],
       [102, 103, 104, 105, 106, 107],
       [108, 109, 110, 111, 112, 113],
       [114, 115, 116, 117, 118, 119]])]

次回はPandasでデータフレーム中の最大値、最小値を取得する方法を紹介します。

ではでは今回はこんな感じで。

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

目次