スタートページ> 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 も対象になる
一般形 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 実務的に稀だし、かなり複雑になりそうです。
選択する項目が多いとき、削除する項目を指定するほうが便利なこともあります。 (これまでの条件に否定 ! や 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
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])
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]])
行を追加 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