スタートページJavaScript他言語Python 目次>    ←配列の生成と要素表現  →配列の計算

配列の部分指定と行・列の追加

ndarray や DataFrame では、配列[i, j] の i, j を [ ] でくくり、特殊な表記をすることにより、部分指定をすることができます。
それにより、配列処理における if や for などの記述を回避することができ、簡素に明瞭な記述ができます。

  ・リスト形式  [k1, k2, k3, …]    列挙した行・列だけを取り出す
  ・スライス形式 [kmin: kmax: dk]    等間隔でで行・列を指定する
  ・条件指定方式 df[df.c1 > 30]    条件に合致した行・列を取り出す
  ・削除指定方式 df.drop([2, 4])     条件に合致したものを削除(合致しないものを取り出す)

逆に、配列に行・列を追加する手段を列挙します。

サンプル

以降、次のデータをサンプルとして用います。

import numpy as np import pandas as pd vlist = [10, 11, 12, 13, 14, 15, 16] varray = np.array([10, 11, 12, 13, 14, 15, 16]) mlist = [[ 0, 1, 2, 3, 4, 5, 6], [10, 11, 12, 13, 14, 15, 16], [20, 21, 22, 23, 24, 25, 26], [30, 31, 32, 33, 34, 35, 36], [40, 41, 42, 43, 44, 45, 46]] marray = np.array([[ 0, 1, 2, 3, 4, 5, 6], [10, 11, 12, 13, 14, 15, 16], [20, 21, 22, 23, 24, 25, 26], [30, 31, 32, 33, 34, 35, 36], [40, 41, 42, 43, 44, 45, 46]]) # c0 c1 c2 c3 c4 c5 c6 df = pd.DataFrame([[ 0, 1, 2, 3, 4, 5, 6], [10, 11, 12, 13, 14, 15, 16], [20, 21, 22, 23, 24, 25, 26], [30, 31, 32, 33, 34, 35, 36], [40, 41, 42, 43, 44, 45, 46]], columns = ['c0','c1','c2','c3','c4','c5','c6']) idf = pd.DataFrame([[ 0, 1, 2, 3, 4, 5, 6], # r0 [10, 11, 12, 13, 14, 15, 16], # r1 [20, 21, 22, 23, 24, 25, 26], # r2 [30, 31, 32, 33, 34, 35, 36], # r3 [40, 41, 42, 43, 44, 45, 46]], # r4 columns = ['c0','c1','c2','c3','c4','c5','c6'], index = ['r0','r1','r2','r3','r4'])

ベクトル・行列の要素指定

ベクトルの要素指定

  vlist[2]        # 12
  varray[2]       # 12

行列の要素指定

・ [i][j]形式はすべて使える。[i,j]形式が使えるのは ndarray だけ。
・ DataFrame では、添え字の順序が [列][行] になる。
・ DataFrame では、.列名[i] の表記ができる。

       [i][j]形式        [i,j]形式             .列名[i]形式
  mlist  mlist[1][2]=12      mlist[1,2]=エラー
  marray  marray[1][2]=12     marray[1,2]=12
  df       df['c2'][1]=12      df['c2',1]=エラー       df.c2[1]=12 
  idf      idf['c2']['r1']=12  idf['c2']['r1']=エラー  idf.c2['r1']=12
           └ すべて使える     └marrayだけに使える

行列の指定行(列)の全要素指定

行列の行指定(指定行の全要素指定)

・ list と ndarray は、行を与えるだけ(列を指定しない)だけでよい。
・ DataFrame では形式的に行名を loc とする

  mlist[1]       # 〇 [10, 11, 12, 13, 14, 15, 16]
  marray[1]      # 〇 array([10, 11, 12, 13, 14, 15, 16])
  df.loc[1]      # 〇  c0  10
  df.loc['r1']   # 〇  c1  11
                 #     c2  12
                 #     c3  13
                 #     c4  14
                 #     c5  15
                 #     c6  16
                 #     └ 列名

行列の列指定(指定列の全要素指定)

・ list では、このような機能はない。
・ ndarrayでは、[:, 列] で指定する。[:][列] は×。
・ DataFrame では、列名を指定するだけでよい。

  mlist[:][2]         # × [20, 21, 22, 23, 24, 25, 26] 行を指定したことになる
  marray[:][2]        # × array([20, 21, 22, 23, 24, 25, 26]) 行を指定したことになる
  marray[:, 2]        # 〇 array([ 2, 12, 22, 32, 42])
  df['c2']            # 〇       df        idf
  df.c2               # 〇     0   2     r0   2
  idf['c2']           # 〇     1  12     r1  12
  idf.c2              # 〇     2  22     r2  22
                      #        3  32     r3  32
                      #        4  42     r4  42
                      #        └ 行番号 ┘

リストによる複数指定

ベクトルの複数要素指定

  vlist[[1,3]]     # エラー
  varray[[1,3]]    # array([11, 13])
  df.c1[[1,3]]     #  1    11
                   #  3    31

行列の複数行指定(指定行の全要素)

  mlist[[1,3]]          # エラー

  marray[[1,3]]         # array([[10, 11, 12, 13, 14, 15, 16], 
                        #        [30, 31, 32, 33, 34, 35, 36]])


  df.loc[[1,3]]         #     c0  c1  c2  c3  c4  c5  c6
                        #  1  10  11  12  13  14  15  16
                        #  3  30  31  32  33  34  35  36

  idf.loc[['r1','r3']]  #     c0  c1  c2  c3  c4  c5  c6
                        # r1  10  11  12  13  14  15  16
                        # r3  30  31  32  33  34  35  36

行列の複数列全行要素、複数行全列要素の指定

  marray[:, [1,3]]    # array([[ 1,  3], [11, 13], [21, 23], [31, 33], [41, 43]])

  df[['c1', 'c3']]      #     c1  c3
                        #  0   1   3
                        #  1  11  13
                        #  2  21  23
                        #  3  31  33
                        #  4  41  43

  marray[1][[2,4]]      # array([12, 14])
  marray[1, [2,4]]      # array([12, 14])

  marray[[1,3]][2]      # 記法エラー
  marray[[1,3], 2]      # array([12, 32])

  df.loc[1][['c2','c4']]      # c2  12
                              # c4  14
  idf.loc['r1'][['c2','c4']]  # c2  12
                              # c4  14

  df.c2[[1,3]]          #   1  12
                        #   3  32
  idf.c2[['r1','r3']]   #  r1  12
                        #  r3  32

行列の複数行・複数列の指定

ndarray の場合
 単に[i],[j]を並べたのでは実現せず、下の2行のようにする必要があります。
 私は、この理由を理解していません。
  marray[[1,3]][[2,4]]            # エラー
  marray[[1,3], [2,4]]            # エラー array([12, 34])
  marray[[1,3]][:, [2,4]]         # array([[12, 14],  [32, 34]])
  marray[np.ix_([1,3], [2,4])]    # array([[12, 14],  [32, 34]])

DataFrame の場合
  df[[1,3],['c2','c4']]             # エラー
  df.loc[[1,3],['c2','c4']]         #      c2  c4
                                    #   1  12  14
                                    #   3  32  34
  idf.loc[['r1','r3'],['c2','c4']]  #      c2  c4
                                    #  r1  12  14
                                    #  r3  32  34

スライス(等間隔列挙)

一般形 [kmin: kmax: dk]
    通常言語での for (k=kmin; k<kmax; k=k+dk) に相当。k=kmax にはならない(;ではなく:)。
  省略時 kmin=0, kmax=len(v), dk=1

・ DataFrame では、行番号を指定するのに loc を用いるが、そのときは k=kmax も対象になる。
・ list はベクトルでは使えるが行列では使えない。
・ ndarray では[i.j]形式を使う。 [i][j]形式ではエラーになる。

ベクトルでのスライス指定

・ すべてのベクトルで使える(DataFrame では列ベクトル)

[2:6:2]     x[2], x[4] が対象 x[6] は対象外
  vlist[2:6:2]    # [12, 14]
  varray[2:6:2]   # array([12, 14])
  df.c1[2:6:2]    # 2    21
                  # 4    41
                  # └ 行番号
省略時  0. len, 1 と解釈
  vlist[1:3]      # [11, 12]     x[3] は含まれない
  vlist[:3]       # [10, 11, 12]
  vlist[5:]       # [15, 16]

行列でのスライス指定(行・列の一方指定)

指定複数行の全列要素
  mlist[1:3]          # [[10, 11, 12, 13, 14, 15, 16], [20, 21, 22, 23, 24, 25, 26]]

  marray[1:3]         # array([[10, 11, 12, 13, 14, 15, 16], [20, 21, 22, 23, 24, 25, 26]])

  df.loc[1:3]         # 行番号3も対象になる。
                      #      c0  c1  c2  c3  c4  c5  c6
                      #   1  10  11  12  13  14  15  16
                      #   2  20  21  22  23  24  25  26
                      #   3  30  31  32  33  34  35  36

  idf.loc['r1':'r3']  #      c0  c1  c2  c3  c4  c5  c6
                      #  r1  10  11  12  13  14  15  16
                      #  r2  20  21  22  23  24  25  26
                      #  r3  30  31  32  33  34  35  36 loc では kmax も対象になる
指定複数列の全行要素
  mlist[:][2:6:2]         # エラー [[20, 21, 22, 23, 24, 25, 26], [40, 41, 42, 43, 44, 45, 46]]
  marray[:][2:6:2]        # エラー  上と同じ 

  marray[:, 2:6:2]        # array([[ 2,  4], [12, 14], [22, 24], [32, 34], [42, 44]])

  df.loc[:, 'c2':'c4':2]  #     c2  c4
                          #  0   2   4
                          #  1  12  14
                          #  2  22  24
                          #  3  32  34
                          #  4  42  44

行列でのスライス指定(行・列の両方指定)

  mlist[1:3][2:6:2]        # エラー
  marray[1:3][2:6:2]       # エラー

  marray[1:3, 2:6:2]       # array([[12, 14], [22, 24]])

  df.loc[1:3, 'c2':'c4':2] #     c2  c4
                           #  1  12  14
                           #  2  22  24
                           #  3  32  34 loc では kmax も対象になる

where 条件による指定

ベクトルでの条件指定

一般形 np.where(varrayの条件式)[0]
要素の値ではなく、要素の番号が戻される

  np.where(varray > 12)            # (array([3, 4, 5, 6],)   v[3]~v[6] が対象
  varray[np.where(varray > 12)]    # array([13, 14, 15, 16])

  np.where(varray%2 == 0)          # array([0, 2, 4, 6],) 値が偶数の要素番号
  varray[np.where(varray%2 == 0)]  # array([10,12,14,16])

列内の条件を与えて合致する行を選択

ndarray
  np.where(marray[:, 1] > 30)      # (array([3, 4]),)   列1の要素>30の行番号

  marray[np.where(marray[:, 1] > 30)]   # array([[30, 31, 32, 33, 34, 35, 36],
                                        #        [40, 41, 42, 43, 44, 45, 46]])

  marray[np.where((marray[:, 1] > 30)|(marray[:, 2] == 12))] # 複合条件も可能。 () はなくてもよい
                                        # array([[10, 11, 12, 13, 14, 15, 16],
                                        #        [30, 31, 32, 33, 34, 35, 36],
                                        #        [40, 41, 42, 43, 44, 45, 46]])
DataFrame
  df[df.c1 > 30]                        #      c0  c1  c2  c3  c4  c5  c6
                                        #   3  30  31  32  33  34  35  36
                                        #   4  40  41  42  43  44  45  46

  df[(df.c1 > 30) | (df.c2 == 12)]      #      c0  c1  c2  c3  c4  c5  c6
                                        #   1  10  11  12  13  14  15  16
                                        #   3  30  31  32  33  34  35  36
                                        #   4  40  41  42  43  44  45  46

行内の条件を与えて合致する列を選択

ndarray
  np.where(marray[2] >= 25)        # (array([5, 6]),)

  marray[:, np.where(marray[2] >= 25)]    # エラー3次元配列になってしまう
          # array([[[ 5,  6]], [[15, 16]], [[25, 26]], [[35, 36]], [[45, 46]]])

  marray[:, np.where(marray[2] >= 25)[0]] # 〇
                  # array([[ 5,  6], [15, 16], [25, 26], [35, 36], [45, 46]])
DataFrame
  実務的に稀だし、かなり複雑になりそうです。

np.delete, df.drop 削除行・列の指定

選択する項目が多いとき、削除する項目を指定するほうが便利なこともあります。
(これまでの条件に否定 ! や not で行うこともできますが)

  ndarray     np.delete(marray, 削除行・列, axis=方向)
  DataFrame   df.drop(削除行・列, axis=方向)

削除行の指定

  np.delete(marray, [2, 4], axis=0)  # array([[ 0,  1,  2,  3,  4,  5,  6],
                                     #        [10, 11, 12, 13, 14, 15, 16],
                                     #        [30, 31, 32, 33, 34, 35, 36]])

  df.drop([2, 4])                    # axis=0 は省略できる

  idf.drop(['r2','r4'])              #     c0  c1  c2  c3  c4  c5  c6
                                     # r0   0   1   2   3   4   5   6
                                     # r1  10  11  12  13  14  15  16
                                   # r3  30  31  32  33  34  35  36

削除列の指定

  np.delete(marray, [2, 4], axis=1) # array([[ 0,  1,  3,  5,  6],
                                     #        [10, 11, 13, 15, 16],
                                     #        [20, 21, 23, 25, 26],
                                     #        [30, 31, 33, 35, 36],
                                     #        [40, 41, 43, 45, 46]])

  df.drop(['c2', 'c4'], axis=1)      # axis=1 が必要
                                     #     c0  c1  c3  c5  c6
                                     #  0   0   1   3   5   6
                                     #  1  10  11  13  15  16
                                     #  2  20  21  23  25  26
                                     #  3  30  31  33  35  36
                                     #  4  40  41  43  45  46

append, insert 配列の追加

ベクトルへのスカラーの追加

vlist への追加
  vlist + 17        # × エラーになる
  vlist + [17]      # 〇 [10, 11, 12, 13, 14, 15, 16, 17]
  vlist.append(17) # 〇 [10, 11, 12, 13, 14, 15, 16, 17]
varray への追加
  varray + 17           # × 全要素に17を加算 array([27, 28, 29, 30, 31, 32, 33])
  varray + [17]         # × 同上
  np.append(varray, 17) # 〇 array([10, 11, 12, 13, 14, 15, 16, 17])

ndarray への追加

np.insert(元行列, 行位置, 追加ベクトル, axis=方向)    # 行の挿入
元行列と追加ベクトルは list でも ndarray でもよい。結果は ndarray になる。

行を追加
  v = [90, 91, 92, 93, 94, 95, 96] # ndarray でもよい。
  np.insert(marray, 3, v, axis=0)  # marray は mlist でもよい。結果は ndarray になる。 
                                   # array([[ 0,  1,  2,  3,  4,  5,  6],
                                   #        [10, 11, 12, 13, 14, 15, 16],
                                   #        [20, 21, 22, 23, 24, 25, 26],
                                   #        [90, 91, 92, 93, 94, 95, 96], ←追加
                                   #        [30, 31, 32, 33, 34, 35, 36],
                                   #        [40, 41, 42, 43, 44, 45, 46]])
列を追加
  v = [9, 19, 29, 39, 49]          #                                     ┌ 追加
  np.insert(marray, 7, v, axis=1)  # array([[ 0,  1,  2,  3,  4,  5,  6,  9],
                                   #        [10, 11, 12, 13, 14, 15, 16, 19],
                                   #        [20, 21, 22, 23, 24, 25, 26, 29],
                                   #        [30, 31, 32, 33, 34, 35, 36, 39],
                                   #        [40, 41, 42, 43, 44, 45, 46, 49]])

DataFrame への追加

行を追加
  df[5] = [90, 91, 92, 93, 94, 95, 96]          # エラー
  idf['r5'] = [90, 91, 92, 93, 94, 95, 96]      # エラー

  df.loc[5] = [90, 91, 92, 93, 94, 95, 96]      #
  idf.loc['r5'] = [90, 91, 92, 93, 94, 95, 96]  #     c0  c1  c2  c3  c4  c5  c6
                                                # r0   0   1   2   3   4   5   6
                                                # r1  10  11  12  13  14  15  16
                                                # r2  20  21  22  23  24  25  26
                                                # r3  30  31  32  33  34  35  36
                                                # r4  40  41  42  43  44  45  46
                                                # r5  90  91  92  93  94  95  96 ←追加

列を追加                                    # 新列名で追加だとわかる         ┌追加
  df['c7'] = [9, 19, 29, 39, 49]                #    c0  c1  c2  c3  c4  c5  c6  c7
                                                # 0   0   1   2   3   4   5   6   9
                                                # 1  10  11  12  13  14  15  16  19
                                                # 2  20  21  22  23  24  25  26  29
                                                # 3  30  31  32  33  34  35  36  39
                                                # 4  40  41  42  43  44  45  46  49

条件による新列の値の設定
  df.loc[df.c6 < 30, 'c7'] = 'A'                #                                ┌追加
  df.loc[df.c6 > 30, 'c7'] = 'B'                #    c0  c1  c2  c3  c4  c5  c6  c7
                                                # 0   0   1   2   3   4   5   6  A
                                                # 1  10  11  12  13  14  15  16  A
                                                # 2  20  21  22  23  24  25  26  A
                                                # 3  30  31  32  33  34  35  36  B
                                                # 4  40  41  42  43  44  45  46  B