numpy – 配列操作 – 抽出

概要

配列の要素や行・列の抽出などに関する操作。

準備として、以下の1次元、2次元配列を考える。

要素の参照

1次元配列の要素の参照は、リストと同じ。

2次元配列の要素は、[行, 列]で指定。行・列の値の考え方は1次元配列の要素と同じ。

行・列の参照

単一の行・列の参照

2次元配列の行の参照は、行番号を指定。

2次元配列の列の参照はややこしくて、[:,列番号]で指定。1つ目の:は行番号のプレースホルダーみたいなものか。

ただし、列を取り出した結果でも、1次元の配列になる。

直接列ベクトルで取り出したい場合は、[:,列番号:列番号+1]で可能。

なお、1次元の配列にndarray.Tを作用させても、1次元配列のままで列ベクトルにはならない。

範囲を指定した行・列の参照

行の範囲を指定して、複数行の行列を返す。

列の範囲を指定する場合。

複数の行・列を指定した参照

連続しない複数の行を取り出した行列をつくるには、[行番号, 行番号, …]とする。

複数列を取り出す場合。

参照であることの注意

以上の操作で取り出された配列は、元の配列への参照を保っているため、その要素を変更すると元の配列の要素も変更される。

元の配列に影響させたくない場合は、copy.copy()、copy.deepcopy()、np.copy()でオブジェクトをコピーする必要がある。

対角要素の取り出し

np.diag()で、2次元配列の対角要素を取り出した1次元配列が得られる。

ただし、その結果は書き込みできない。

条件を指定した取り出し

配列に条件式を適用して、各要素が要件に合致していればTrue、合致していなければFalseを要素とする配列を返す。

上で得られた配列を要素とすることで、条件に合致した要素のみを取り出した1次元配列を得る。

 

Python3 – numpyのインストール

numpyのインストールは、コマンドラインからpipで。numpyのインストール後にpipのアップグレードを推奨されたので、これも実行。

 

Python3 – random/乱数

概要

randomモジュールには、疑似乱数を発生させる関数や、コレクションからランダムな要素を選んだり、コレクションをシャッフルしてくれる関数が用意されている。

なお、numpy.randomモジュールにも便利な乱数生成関数が準備されている。

乱数系列/seed()

random.seed()関数は、引数を指定して乱数系列を固定する。

疑似乱数/random()

random()関数は、0≤r<1の範囲の一様乱数を浮動小数点で返す。

一様乱数/uniform()

uniform(a, b)は、a≤r<bの範囲の一様乱数を浮動小数点で返す。

整数乱数/randint(), randrange()

randint(a, b)a≤r≤bの範囲の乱数を整数で返す。第2引数のbも生成されることに注意。

randrange(start, end, step)start≤r<stopの範囲でstep間隔の乱数を整数で返す。第2引数のstopは生成されないことに注意。stepを省略した場合は1となる。

ランダム選択/choise()

choise(c)はコレクションcからランダムな要素を一つ選んで返す。

引数に文字列を指定すると、その中から任意の位置の文字を一つ返す。

シャッフル/shuffle()

shuffle(c)はコレクションの内容をシャッフルする。イミュータブルな文字列を指定するとTypeErrorになる。

 

Python3 – オブジェクトへの参照

概要

Pythonで関数の受け渡しが参照渡しとされているが、改めて変数とオブジェクトの関係を含めて確認してみた。

オブジェクトの参照に関する基本的な考え方は

  • 論理値や数値も含めて全てオブジェクト
  • 変数にはインスタンスのアドレスが格納され、参照される
  • 数値や文字列などイミュータブルなオブジェクトの場合、リテラルの表現が同じものは共通の1つのインスタンスとなる
  • リストなどミュータブルなオブジェクトは、インスタンスの内容が変更されても参照先は変わらない(逆に言えば、参照先が変わらないのに内容が変更されている可能性がある)

関数の引数の受け渡しは

  • 仮引数は、関数が呼び出し時には元のオブジェクトへの参照を指しているが、イミュータブルオブジェクトが変更された場合は参照先が変わり、呼び出し元の引数に影響を与えない
  • 引数の参照先がミュータブルオブジェクトの場合、インスタンスの内容が変更されても参照先は変わらず、呼び出し元の内容も変更される

変数からオブジェクトへの参照

数値の場合

下記のコードをまず確認する。

ある数値を変数に代入すると、その変数には数値(オブジェクト)のアドレスがセットされる。その変数の内容(アドレス)を別の変数に代入すると、新しい変数も同じアドレスをさすようになる。

次に、同じ数値を指している変数の一つに別の数値を代入すると、その変数は新しい数値オブジェクトのアドレスを指すようになる。

以下のように、同じ値の数値は1つのオブジェクトのアドレスが共有される。

数値計算の場合も、結果が同じ値なら1のオブジェクトが共有される。

変数が絡む演算でも、結果が同じ値なら同じアドレスを指す。

浮動小数点の場合、精度上少しでも異なる値は違うオブジェクトになる。

文字列の場合

数値の場合と同じで、変数は文字列オブジェクトのアドレスを指す。

異なる内容の文字列は、異なるオブジェクトとなる。

同じ内容の文字列リテラルは、異なる位置で用いられても1つのオブジェクトとして共有される。

面白いことに、文字列リテラル同士の演算結果が同じなら、これも同じオブジェクトとして共有される。

同じオブジェクトを指していても、一方に演算を施すと新たなオブジェクトが生成されるため、異なるオブジェクトを指すようになる。

なお、リテラル同士の演算で結果が同じ場合はオブジェクトが共有されたが、変数が絡む場合は、内容が同じであっても異なるオブジェクトとなる。

リストの場合

リストの場合もオブジェクトへの参照が変数に保存される。

リストの要素を変更した場合、そのリストを指している全ての変数に変更結果が反映される。

注意点。リストの場合、リテラルが同じでも異なるオブジェクトが生成される。

オブジェクトが異なるため、片方の変更は他方に反映されない。

関数の引数の参照

数値の場合

関数の引数に数値を渡す場合の流れは以下の通り。

  1. 仮引数は引数と同じオブジェクトを指す
  2. 関数内で引数が変更されると、新たなオブジェクトを指すようになる
  3. その結果、仮引数に渡した変数は変更されない

文字列の場合

文字列の場合も、関数内での変更は呼び出し元に影響を与えない。

リストの場合

リストを引数に渡した場合、関数内での変更が呼び出し元にも影響を与える。リストのようなミュータブルオブジェクトの場合、それに対する変更は元のインスタンスに対する変更であり、イミュータブルなオブジェクトのように新しいインスタンスが生成されるわけではないため。

元のインスタンスに影響を波及させたくない場合はコピー、ディープコピーを使う。

 

Python3 – キーワードと予約語

キーワード

キーワードの一覧は以下の通り。

False, None, True, and, as, assert, async, await, break, class, continue, def, del, elif, else, except, finally, for, from, global, if, import, in, is, lambda, nonlocal, not, or, pass, raise, return, try, while, with, yield

組み込み関数

このうちabs以降の一覧は以下の通り。

abs, all, any, ascii, bin, bool, breakpoint, bytearray, bytes, callable, chr, classmethod, compile, complex, copyright, credits, delattr, dict, dir, divmod, enumerate, eval, exec, exit, filter, float, format, frozenset, getattr, globals, hasattr, hash, help, hex, id, input, int, isinstance, issubclass, iter, len, license, list, locals, map, max, memoryview, min, next, object, oct, open, ord, pow, print, property, quit, range, repr, reversed, round, set, setattr, slice, sorted, staticmethod, str, sum, super, tuple, type, vars, zip

 

Python3 – 文字を順に取り出す

数字やアルファベットの文字を順に取り出して使いたい時、stringモジュールを使うと便利。

 

Python3 – 数値と文字列の相互変換

数値から文字列への変換

10進数(str関数)

str関数で引数の数値を文字列化。

整数の場合、桁数が多くてもそのまま文字列化される。

実数の場合は有効数値で丸められる。

浮動小数点で与えると、桁数が収まる範囲で固定少数表示の文字列になる。

2進数、8進数、16進数

組み込み関数を使う方法

bin、oct、hex関数を使った場合、プレフィックス’0b’、’0o’、’0x’がついた文字列になる。

format関数を使う方法

format関数の第2引数に基数に対応した文字を指定する。

第2引数で、桁数を指定して空いた上位桁を0で埋めることができる。

書式文字列を使う方法

書式文字列と%演算子を使っても、数値を文字列化できるが、2進数には対応していない。

文字列から数値への変換

10進数

整数(int関数)

int関数は整数の文字列を数値化するが、実数形式の文字列を与えるとエラーになる。

実数(float関数)

float関数は実数の文字列を数値化する。固定小数点/浮動小数点のどちらの表現でもかまわない。

2進数、8進数、16進数

int関数の第2引数で基数を指定する。

第2引数には2~36まで指定可能で、0~9とA~Zまで使った36進法まで変換可能。

‘0b’、’0o’、’0x’のプレフィックスを付けた文字列を変換するときは、第2引数を0にする。この場合、10進数も変換可能。

 

Python3 – 数値

int型

整数型はintで表される。

桁数が多くなってもint型として扱われる。

int型のチェック

float型

数値リテラルに小数点を付けるとfloat型として扱われる。float型はCやFORTRANの倍精度の精度。

‘/’による除算の結果は常にfloat型になる。

‘//’による除算では商が整数化される(整数除算と剰余を参照)。

 

Python3 – 書式設定~format

format関数

一つの数値・文字列の書式を設定する場合、format組み込み関数が使える。引数はリテラルでも変数でもよい。

formatメソッド

文字列に対するformatメソッドでも数値・文字列の書式を設定できる(書式設定の書き方は後述)。引数はリテラルでも変数でもよい。

formatメソッドは複数の数値・文字列を扱える。

位置引数として整数を指定し、繰り返して利用することが可能。

キーワード引数として文字列を指定可能。

リストを引数にするときは整数の位置引数とリスト内の引数で指定する。複数のリストを指定するときは位置引数を0、1…と対応させていく。

辞書を引数にするときは整数の位置引数とキーで指定する。キーはクォートで囲まない。

書式設定する場合は、[位置引数]:[書式設定文字列]の形式にする。位置引数を指定しない場合でも':'は必要。

書式設定文字列

formatメソッド

位置引数を省略して書式設定文字列を各場合{:[書式設定文字列]}のように':'を省略することができない。

文字列

{:[</^/>][width]}で左寄せ/中央ぞろえ/右寄せと、全体の幅widthを指定。

{:[char][</^/>][width]}で空白部分をcharの文字でパディング

整数

整数の書式は幅の値に'd'を続けて書く。

整数を2進数、8進数、16進数で表現できる。

基数を指定するとき、'#'を前置すると0b、0o、0xが前に付加される。以下の例では、同時に幅も指定している。2進数表現の場合は0bを付加すると設定幅を超えるので、そのまま表示されている。

浮動小数点

浮動小数点形式の実数の書式は、小数部の桁数だけ指定するときは".3f"のように、幅を設定するときは"10.3f"のように指定する。

固定小数点

固定小数点形式の実数の書式は、小数部の桁数だけ指定するときは".5e"のように、幅を指定するときは"15.5e"のように指定する。

符号の表示方法

正の数値に対して'+'を表示させるときは、数値書式の前に'+'をつけ、正の時にスペースを表示させるときには' 'をつける。

 

指定した幅の先頭に符号等を表示し、右寄せの数値との間をパディングする方法。

format関数

基数表示

数値の基数を指定して、10進数、2進数、8進数、16進数を表示。16進数は英文字の大文字/小文字を選択可能。

位置揃え

文字列や数値を固定幅の中で左寄せ、センタリング、右寄せ(センタリングで左右幅が異なるときは、左に1桁寄せられる)。

パディング

数値を固定幅で表示した場合のデフォルトは右寄せ。'[任意の文字]=’で空白をパディング。特にゼロで埋める場合は’=’を省略できる。

2、8、16の基数に対して固定幅で0でパディングする例。

+符号

‘+’を指定すると、正の値の時に+記号がつく。

カンマ区切り

3桁ごとのカンマ区切り指定。

固定小数点実数

固定小数点の小数部の桁数を’.[桁数]f’で指定する。

浮動小数点実数

浮動小数点の小数部の桁数を’.[桁数]e’で指定する。

実数全体の桁数

小数部の桁数ではなく全体の桁数を’.[桁数]g’で指定する。全体の桁数が整数部の桁数以上のときは、固定小数点で表示される。

 

Python3 – 整数除算と剰余(//, %)

//演算子

//演算子は、切り捨て除算と言われることが多いが、正確には小数部の切り捨てではなく、除算値を超えない最大の整数となる。これは実数の除算結果にfloorを適用した値と同じで、除算結果が負の時に注意を要する。

なお、被除数・除数の何れがマイナスかは問わず、計算結果がマイナスかどうかだけによる。

%演算子

%演算子は、引数の剰余(mod)を与える。除数の正負によって挙動が異なる点に注意。

除数が正のとき剰余は正となり、除数が負のときは剰余は負となる。

 \begin{array}{lcl} 13 \% 3 = 1 & \Rightarrow & 13 = 3 \times 4 + 1 \\ -13 \% 3 = 2 & \Rightarrow & -13 = 3 \times (-5) + 2 \\ 13 \% (-3) = -2 & \Rightarrow & 13 = -3 \times (-5) - 2 \\ -13 \% (-3) = -1 & \Rightarrow &  -13 = -3 \times 4 -1 \end{array}