スタートページJavaScript他言語Python 目次>    ←配列の部分指定と行・列の追加  →DataFrame のSQLライクな操作

配列の計算

Python での計算は、あくまでもスカラー間の計算です。
list配列全体に同じ演算をするには forループ などを用いることになります。


配列を対象にした場合、mlist[1][2] はスカラーなので、mlist[1][2] = 100 はできます。
しかし、mlist = 100 のように配列要素全体を対象にする式はエラーになります。
このときは for ループを用いたプログラムを作成する必要があります。

それに対して、NumPy で marray = np.array([…],[…],…]) のように定義した ndarray配列では、
marray = 100 の1行で全要素を100にするような命令ができます。

Python では基本的にスカラー間の演算ですので、
ここでは主に、ndarray と DataFrame を対象にします。

基本的な演算

サンプルデータ

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

import numpy as np import pandas as pd vlist = [10, 11, 12, 13] varray = np.array([10, 11, 12, 13]) mlist = [[ 0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23]] marray = np.array([[ 0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23]]) # c0 c1 c2 c3 df = pd.DataFrame([[ 0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23]], columns = ['c0','c1','c2','c3'])

スカラーとの計算

配列の全要素に加減乗除が行われます
  varray + 100     # 〇 array([110, 111, 112, 113])
  marray * 2       # 〇 array([[ 0,  2,  4,  6], [20, 22, 24, 26], [40, 42, 44, 46]])
  df + 100         # 〇 全要素が +100 されます
  df['c1'] + 100   # 〇 c1列の列要素が +100 されます
  df.loc[1] * 2    # 〇 行番号1の行要素が *20 されます
順を逆にしても、同じ結果になります。
  100 - varray     # 〇 array([90, 89, 88, 87])

ベクトル間の加減算

双方のベクトルの長さが同じでなければなりません。順を逆にしても、同じ結果になります。
  v = [100, 100, 100, 100]   # v は ndarray でも同じです。 
  varray + v                 # 〇 array([110, 111, 112, 113])
  df.loc[1] + v              # 〇 行番号1の行要素が加算されます
  v = [100, 100, 100]
  df['c1'] + v               # 〇 c1列の列要素が +100 されます。

ベクトル間の対応する要素の乗除算

双方のベクトルの長さが同じでなければなりません。
  v = [1, 2, 3, 4]
  varray * v                  # 〇 array([10, 22, 36, 52])
  v * varray                  # 〇 同上
  df.loc[1] * v               # 〇
  v = [1, 2, 3]
  df['c1'] * v                # 〇 1 22 63 になる
                   # df['c1'] が縦ベクトル、v が横ベクトルなのに、各要素の乗算になる 

ベクトルの積(結果はスカラーになる)@演算子

内積には * ではなく @ を用います。
双方のベクトルの長さが同じでなければなりません。
被乗数のベクトルが横ベクトルでも縦ベクトルでも構いません。
  v = [1, 0, 1, 0]
  varray @ v                   # 〇 22 (=10*1 + 11*0 + 12*1)
  df.loc[1] @ v                # 〇 同上

  v = [1, 0, 1]
  df['c1'] @ v                 # 〇 22 (=1*1 + 11*0 + 12*1)
  v @ df['c1']                 # 〇 同上

行列とベクトルの計算

各列に横ベクトルを加算・乗算する
 v = [100, 200, 300, 400]
  marray + v                    # 〇 array([[100, 201, 302, 403],
                                #            [110, 211, 312, 413],
                                #            [120, 221, 322, 423]])

  marray * v                    # 〇 array([[   0,  200,  600, 1200],
                                #            [1000, 2200, 3600, 5200],
                                #            [2000, 4200, 6600, 9200]])

  df + v                        # 〇     c0   c1   c2   c3
                                #     0  100  201  302  403
                                #     1  110  211  312  413
                                #     2  120  221  322  423

  df.add(v, axis=1)             # 〇 同上

  df.mul(v, axis=1)             # 〇

各行に縦ベクトルを加算・乗算する
 v = [[100], [200], [300]]     # 縦ベクトルにする必要がある
  marray + v                    # 〇 array([[100, 101, 102, 103],
                                #            [210, 211, 212, 213],
                                #            [320, 321, 322, 323]])

  marray * v                    # 〇 array([[   0,  100,  200,  300],
                                #            [2000, 2200, 2400, 2600],
                                #            [6000, 6300, 6600, 6900]])

  df + v                      # × エラー v が縦ベクトル
  df * v                        # × エラー

各行に横ベクトルを加算・乗算する
 v = [100, 200, 300]           # 横ベクトル
  df.add(v, axis=0)             # 〇    c0   c1   c2   c3
                                #     0  100  101  102  103
                                #     1  210  211  212  213
                                #     2  320  321  322  323

  df.mul(v, axis=0)             # 〇   c0    c1    c2    c3 
                                #    0     0   100   200   300
                                #    1  2000  2200  2400  2600
                                #    2  6000  6300  6600  6900

行列と行列の各対応する要素間の計算

両方のサイズが同じでなければなりません。
  m = [[1000, 1100, 1200, 1300],    # m は mlist, marray どちらでも有効です。
       [2000, 2100, 2200, 2300],
       [3000, 3100, 3200, 3300]]
ndarray では「行列とベクトル」での方法と同じです。
  marray + m                # 〇 array([[1000, 1101, 1202, 1303],
                              #           [2010, 2111, 2212, 2313],
                              #           [3020, 3121, 3222, 3323]])
  marray * m                # 〇 array([[    0,  1100,  2400,  3900],
                              #            [20000, 23100, 26400, 29900],
                              #            [60000, 65100, 70400, 75900]])

DataFrame のときは、m は転置してサイズを合わせる必要があります。
  m = [[1000, 2000, 3000],
       [1100, 2100, 3100],
       [1200, 2200, 3200],
       [1300, 2300, 3300]]

  df * m                    # 〇     c0     c1     c2     c3
                              #    0      0   1100   2400   3900
                              #    1  20000  23100  26400  29900
                              #    2  60000  65100  70400  75900

行列の積(内積) @

内積には * ではなく @ を用います。
行列Aのサイズを (ma*na)、Bを (mb*nb) としたとき、na = mb でなければならず、
結果は ma*nb は配列になります。
  m = [[0, 1],   # mlist でも marray でもよい
       [1, 0],
       [0, 1],
       [1, 0]]

  marray @ m     # 〇 array([[ 4(= 0*0 +  1*1  +  2*0 +  3*1),  2(= 0*1 +  1*0  +  2*1 +  3*0)],    
                 #            [24(=10*0 + 11*1  + 12*0 + 13*1), 22(=10*1 + 11*0  + 12*1 + 13*0)],
                #            [44(=20*0 + 21*1  + 22*0 + 23*1), 42(=20*1 + 21*0  + 22*1 + 23*0)]])

  df @ m         # 〇  0   1  列名が失われます。
                 #   0   4   2
                 #   1  24  22
                 #   2  44  42

転置行列 T

転置行列とは、行・列を入れ替えた行列です。T属性を用います。
ベクトルには使えません。行列だけです。
list の行列には使えません

  marray = np.array([[ 0,  1,  2],
                     [10, 11, 12]])

  marray.T    # array([[ 0, 10],
              #        [ 1, 11],
              #        [ 2, 12]])

  df = pd.DataFrame([[ 0,  1,  2],
                     [10, 11, 12]],
                   columns = ['c0','c1','c2'],
                   index = ['r0','r1'])

  df.T        #    r0  r1
              # c0  0  10
              # c1  1  11
              # c2  2  12

DataFrame での二項演算関数

一般形: df.xxx(変数、axis = 'columns')
    xxx = add(+)、sub(-)、mul(*)、div(/,//)、mod(%)、pow(**)
    axis = 0(横方向), 1(縦方向)
機能は二項演算子と同じで、二項演算子を用いるほうが簡便ですが、上記のように、行を対象にする場合は、これを用いるのが便利です。

関数

数学関数

  NumPy では、通常のプログラム言語で提供しているものと同等な関数を提供しています。
  通常は、変数がスカラーなら戻り値もスカラー、配列なら戻り値も配列になります。

 元データ
  import numpy as np
  import pandas as pd
  s = 4
  vlist = [4, 9]
  marray = np.array([[4, 9], [16, 25]])
  df = pd.DataFrame([[4, 9], [16, 25]], columns= ['c0','c1'])
 関数
  np.sqrt(s)       # 2.0
  np.sqrt(vlist)   # array([2., 3.])
  np.sqrt(marray)  # array([[2., 3.], [4., 5.]])
  np.sqrt(df)      #     c0   c1
                   #  0  2.0  3.0
                   #  1  4.0  5.0

代表的な数学関数
  累乗(np.power)・平方根(np.sqrt)、三角関数(np.sin, np.cos, np.tan)、指数関数(np.exp)、対数関数(np.log)、
  切り捨て(np.floor)、切り上げ(np.ceil)、四捨五入(np.round)、絶対値(np.abs)、…

  参照:DepAge「NumPyの数学関数・定数まとめ」

統計基本量の関数

  NumPy、Pandas での基本的な関数を列挙します。
   sum(): 合計、mean(): 平均、min(): 最小、max(): 最大、std(): 標準偏差、var(): 分散など

  一般形: A np.sum(配列, axis=0/1)  list, ndarray, DataFrame 全てに使える
           B 配列.sum(axis=0/1)      list には使えない
            axis 全体を対象にするときは与えない 結果はスカラー
                            =0 行列の縦方向集計 結果はサイズ列数のベクトル
                             1 行列の横方向集計 結果はサイズ行数のベクトル

サンプルデータ

ここでは次のデータをサンプルとして用います。

import numpy as np import pandas as pd varray = np.array([10, 11, 12, 13]) marray = np.array([[ 0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23]]) # c0 c1 c2 c3 df = pd.DataFrame([[ 0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23]], columns = ['c0','c1','c2','c3'])

sum での例

ベクトル 結果はスカラー
  vlist.sum()      # エラー
  np.sum(vlist)    # 〇 46 (= 10+11+12+13)

  np.sum(varray)   # 〇 46
  varray.sum()     # 〇 46

  np.sum(df['c1']) # 〇 33 (= 1+11+21)
  df['c1'].sum()   # 〇 33

行列全体 結果はスカラー
  np.sum(marray)   # 〇 138
  marray.sum()     # 〇 138

  np.sum(df)       # × 各列ごとの集計になる 30 33 36 39
  df.sum()         # × 各列ごとの集計になる 30 33 36 39
  df.sum().sum()   # 〇 138

行列の縦方向集計 結果はサイズ列数のベクトル
  np.sum(marray, axis=0)    # 〇 array([30, 33, 36, 39])
  marray.sum(axis=0)        # 〇

  np.sum(df)                # 〇
  np.sum(df, axis=0)        # 〇

  df.sum()               # 〇 c0    30
                            #     c1    33
                            #     c2    36
                            #     c3    39
  df.sum(axis=0)            # 〇

行列の横方向集計 結果はサイズ行数のベクトル
  np.sum(marray, axis=1)    # 〇 array([ 6, 46, 86])
  marray.sum(axis=1)        # 〇

  np.sum(df, axis=1)        # 〇

  df.sum(axis=1)            # 〇 0     6
                            #     1    46
                            #     2    86

ソート

サンプルデータ

ここでは次のデータをサンプルとして用います。

import numpy as np import pandas as pd vlist = [300, 112, 412, 513, 214] varray = np.array([300, 112, 412, 513, 214]) marray = np.array([[ 0, 400, 2, 3, 4], [300, 100, 300, 500, 200], [600, 500, 22, 23, 24], [ 30, 200, 32, 33, 34], [ 40, 400, 42, 43, 44]]) df = pd.DataFrame([[ 0, 400, 2, 3, 4], [300, 100, 300, 500, 200], [600, 500, 22, 23, 24], [ 30, 200, 32, 33, 34], [ 40, 400, 42, 43, 44]], columns = ['c0','c1','c2','c3','c4'])

ベクトルのソート

  np.sort(vlist)             # array([112, 214, 300, 412, 513]) list も ndarray になる
  np.sort(varray)            # 上と同じ
  np.sort(varray)[::-1]      # 降順 array([513, 412, 300, 214, 112])
                 #     元の配列は維持 array([300, 112, 412, 513, 214])

 次の記述もできます(list は使えない)。しかし元の配列は破壊されます
    varray.sort()              # array([112, 214, 300, 412, 513])
                               #      元の配列は破壊 array([112, 214, 300, 412, 513])

ベクトルの順序づけ argsort

  np.argsort(vlist)               # array([1, 4, 0, 2, 3]) これ以外は list は使えません

  np.argsort(varray)              # array([1, 4, 0, 2, 3])
                                  #   varray[1] は順序1, [2]は順序4, [3]は順序0, … になる
  varray.argsort()                # 上と同じ
  varray[np.argsort(varray)]      # array([112, 214, 300, 412, 513]) # 上の順序に並べた
  varray[varray.argsort()]        # 同上
  varray[varray.argsort()[::-1]]  # 降順 array([513, 412, 300, 214, 112])
                               #   元の配列は維持 array([300, 112, 412, 513, 214])

ndarrayのソート

 その指定した行の横ベクトル、列の縦ベクトルにargsortを適用し、それにより行列をソートします。
  marray[:, marray[行番号].argsort()[::-1]]
  marray[marray[:,列番号].argsort(), :]
  marray[marray[:,列番号].argsort()[::-1], :]

指定行の横ベクトルの昇順 marray[:, marray[行番号].argsort()]

  marray[:, marray[1].argsort()]        # array([[400,   4,   0,   2,   3],
                                        #        [100, 200, 300, 300, 500], 指定行 昇順
                                        #        [500,  24, 600,  22,  23],
                                        #        [200,  34,  30,  32,  33],
                                        #        [400,  44,  40,  42,  43]])
指定行の横ベクトルの降順 marray[:, marray[行番号].argsort()[::-1]] 

  marray[:, marray[1].argsort()[::-1]]  # array([[  3,   2,   0,   4, 400],
                                        #        [500, 300, 300, 200, 100], 指定行 降順
                                        #        [ 23,  22, 600,  24, 500],
                                        #        [ 33,  32,  30,  34, 200],
                                        #        [ 43,  42,  40,  44, 400]])

指定列の縦ベクトルの昇順 marray[marray[:,列番号].argsort(), :]

  marray[marray[:,1].argsort(), :]      # array([[300, 100, 300, 500, 200],
                                        #        [ 30, 200,  32,  33,  34],
                                        #        [  0, 400,   2,   3,   4],
                                        #        [ 40, 400,  42,  43,  44],
                                        #        [600, 500,  22,  23,  24]])
                                        #               └ 指定列 昇順

指定列の縦ベクトルの降順  marray[marray[:,列番号].argsort()[::-1], :]
  省略

指定行が複数の場合
  順位の低い行(列)で先にソートし、次に順位の高い行(列)でソートします。
  marray を維持するなら次のようにしてソート後行列を work にします。
  work をすべて marray にすれば、marray はソート後の行列に置き換わります。

  work = marray[:, marray[2].argsort()]
  work = work[:, work[1].argsort()]     #                   ┌   ┌ 第1順位では同じ値
  work                                  # array([[400,   4,   2,   0,   3],
                                        #        [100, 200, 300, 300, 500], 第1順位
                                        #        [500,  24,  22, 600,  23], 第2順位
                                        #        [200,  34,  32,  30,  33],
                                        #        [400,  44,  42,  40,  43]])

DataFrame のソート

  実務的には、特定の列によるソートがほとんどでしょう。
  元の df は保存されます。

指定列の縦ベクトルによる昇順 df.sort_values(キー列名)
  df.sort_values('c1')                   #      c0   c1   c2   c3   c4
                                         #  1  300  100  300  500  200
                                         #  3   30  200   32   33   34
                                         #  0    0  400    2    3    4
                                         #  4   40  400   42   43   44
                                         #  2  600  500   22   23   24

指定列の縦ベクトルによる昇順 df.sort_values(キー列名, ascending=False)
  df.sort_values('c1', ascending=False)  #      c0   c1   c2   c3   c4
                                         #  2  600  500   22   23   24
                                         #  0    0  400    2    3    4
                                         #  4   40  400   42   43   44
                                         #  3   30  200   32   33   34
                                         #  1  300  100  300  500  200

複数の指定列によるソート df.sort_values([キー1, キー2], ascending=[True, False]) 
                      ソート順位   ソートキーに対応した昇順・降順
  df.sort_values(['c1','c0'], ascending=[True, False])
                                         #      c0   c1   c2   c3   c4
                                         #  1  300  100  300  500  200
                                         #  3   30  200   32   33   34
                                         #  4   40  400   42   43   44 c2の降順
                                         #  0    0  400    2    3    4 同上
                                         #  2  600  500   22   23   24