スタートページ> 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