Python Numpy⑤ - 行列を連結する

今回は、Numpy行列を連結してみます。

行列を連結する

まずNumpyをインポートし、2行3列の行列を2つ作成します。

[コード]

1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np

# 1つめの2次元配列を定義
x = np.array([[1, 2, 3], [4, 5, 6]])
print('行列 x')
print(x)
print()

# 2つめの2次元配列を定義
y = np.ones((2, 3))
print('行列 y')
print(y)

[実行結果]

行列 x
[[1 2 3]
 [4 5 6]]

行列 y
[[1. 1. 1.]
 [1. 1. 1.]]

numpy.r_[]を使うと、行について連結することができます。

[コード]

1
2
z = np.r_[x, y]
print(z)

[実行結果]

[[1. 2. 3.]
 [4. 5. 6.]
 [1. 1. 1.]
 [1. 1. 1.]]

numpy.c_[]を使うと、列について連結することができます。

[コード]

1
2
z = np.c_[x, y]
print(z)

[実行結果]

[[1. 2. 3. 1. 1. 1.]
 [4. 5. 6. 1. 1. 1.]]

Python Numpy④ - 転置をとる/行列の形状を変える

Numpy行列の転置をとる方法と形状を変える方法を試してみます。

転置をとる

まずNumpyをインポートし、2行3列の行列を作成します。

1
2
3
4
import numpy as np

# 2次元配列を定義
x = np.array([[1, 2, 3], [4, 5, 6]])

転置をとるにはシンプルに .T とするだけです。

[コード]

1
2
3
4
5
6
print('転置前')
print(x)
print()

print('転置後')
print(x.T)

[実行結果]

転置前
[[1 2 3]
 [4 5 6]]

転置後
[[1 4]
 [2 5]
 [3 6]]

3次元配列を転置することも可能です。

[コード]

1
2
3
4
5
6
7
8
9
# 3次元配列を定義
x = np.array([[[1, 2], [3, 4], [5, 6]]])

print('転置前')
print(x)
print()

print('転置後')
print(x.T)

[実行結果]

転置前
[[[1 2]
  [3 4]
  [5 6]]]

転置後
[[[1]
  [3]
  [5]]

 [[2]
  [4]
  [6]]]

データだけをみるとよく分かりませんが、形状を確認すると逆順になっていることが分かります。

[コード]

1
2
3
4
5
6
print('転置前')
print(x.shape)
print()

print('転置後')
print(x.T.shape)

[実行結果]

転置前
(1, 3, 2)

転置後
(2, 3, 1)

形状を変える

配列の形状を変えるには reshapeメソッド を使います。

[コード]

1
2
3
4
5
6
# 2行3列の配列を定義
x = np.array([[1, 2, 3], [4, 5, 6]])

# 1行6列の配列に変更します。
y = x.reshape(1, 6)
print(y)

[実行結果]

[[1 2 3 4 5 6]]

配列を変換する場合、要素数が一致しないとエラーになりますので気を付けてください。

Python Numpy③ - 行列の要素へのアクセス

Numpy行列の要素へのアクセスを試してみます。

行列の要素へのアクセス

まずNumpyをインポートし、2行3列の行列を作成します。

1
2
3
import numpy as np

x = np.array([[1, 2, 3], [4, 5, 6]])

2行3列目の要素を取得するには次のように指定します。

1
print(x[1, 2])

添え字は0から始まるため2行目は 1、3列目は 2 と指定します。

[実行結果]

6

1行目の行をそのまま取得します。
1
print(x[0])

[実行結果]

[1 2 3]

2次元配列のまま1列目だけを取得します。

1
print(x[:, 0:1])

[実行結果]

[[1]
 [4]]

1次元配列で1列目を取得します。

1
print(x[:, 0])

[実行結果]

[1 4]

Python Numpy② - リストから行列を作成

リスト型データからNumpyの行列を作成します。

リストデータから配列を作成する

まず、以下のようにNumpyをインポートしておきます。

1
import numpy as np

1次元配列を作成します。

Numpyでは (3, ) という配列の形で表現されます。

1
2
x = np.array([1, 2, 3])
print(x)

[実行結果]

[1 2 3]

次に2行3列の2次元データを作成します。

元となるデータは、リスト型データの中にリスト型データがあるイメージです。

Numpyでは (2, 3) という配列の形で表現されます。

1
2
3
x = np.array([[1, 2, 3], [4, 5, 6]])
print(x)

[実行結果]

[[1 2 3]
 [4 5 6]]

配列の形とデータ型を取得する

配列の形は shape という属性で取得することができます。

1
print(x.shape)

[実行結果]

(2, 3)

データ型は dtype という属性で取得することができます。
1
print(x.dtype)

[実行結果]

int32

Python Numpy① - 行列の作成

Numpyを使うとPythonで行列が簡単に扱えるようになります。

指定した大きさの配列を作成する

まず、以下のようにNumpyをインポートしておきます。

1
import numpy as np

ゼロ埋めの配列を作成する場合には下記のように書きます。

1
2
3
# 2行3列のゼロ埋めの配列を作成
x = np.zeros((2, 3))
print(x)

[実行結果]

[[ 0.  0.  0.]
 [ 0.  0.  0.]]

デフォルトではデータ型が numpy.float64 となりますがint型にしたい場合は、次のようにdtypeを指定します。
1
2
3
# 2行3列のゼロ埋めの配列を作成(int型)
x = np.zeros((2, 3), dtype=int)
print(x)

[実行結果]

[[0 0 0]
 [0 0 0]]

ゼロ埋めではなく 1埋めにしたい場合はnp.ones()メソッドを使用します。
1
2
3
# 2行3列の1埋めの配列を作成
x = np.ones((2, 3))
print(x)

[実行結果]

array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])

Python - 順序付き辞書

Pythonの辞書型データは、キーと値をセットで管理でき記述方法も簡潔なのでとても便利なのですが、順序が保障されないため順番に管理したい場合に困ることがあります。

OrderedDictを使うと順序付きの辞書型としてデータを扱うことができます。

コード

OrderedDictを使うためには、まずimport文を記述する必要があります。
(ここが一般的な辞書型を使うよりも手間に感じます。)

1
2
3
4
5
6
7
8
9
10
from collections import OrderedDict

dict = OrderedDict()

dict['key1'] = 'value1'
dict['key2'] = 'value2'
dict['key3'] = 'value3'
dict['key4'] = 'value4'

print(dict)

実行結果

実行結果は次のようになります。

OrderedDict([('key1', 'value1'), ('key2', 'value2'), ('key3', 'value3'), ('key4', 'value4')])

辞書に追加した順でデータが並んでいることが分かります。

私が辞書型データを使う場合には、順番を考慮することが多いのでこのOrderedDictを標準の辞書型データとして欲しいくらいです。

Python fabric - 管理タスクの実行

アプリケーションのデプロイやシステム管理タスクを行うツールとしてfabicモジュールをご紹介します。

fabicモジュールを使うと、ローカルやリモートでのコマンド実行や、ファイルのアップロード・ダウンロードが簡単にできるようになります。

インストール

次のコマンドを実行しfabicをインストールします。

1
2
3
4
# インストール
pip install fabric3


コード

fabfile.pyを作成し、次のようなコードを書きます。ファイル名は必ずfabfile.pyにする必要があります。

4行目から7行目は環境に応じて設定して下さい。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from fabric.api import *

# 接続情報を設定
env.hosts = ['IPアドレス']
env.user = 'ユーザ名'
env.password = 'パスワード'
env.port = ポート番号

# タスクとなる関数を定義
# この関数名がfabコマンドを実行する際の引数になります。
def task1():
# ローカルでのコマンド実行
res = local('ipconfig')
print('res[{}]'.format(res)) # なぜか結果が格納されない

# コマンド実行
res = run('crontab -l')
print('res[{}]'.format(res))

# sudoでコマンド実行
res = sudo('crontab -l')
print('res[{}]'.format(res))

# ディレクトリを移動してコマンド実行
with cd('/tmp/'):
res = run('pwd')
print('res[{}]'.format(res))

# ファイルを転送する(ローカル → サーバ)
# *等を使ったパターン指定も可能
put('test.txt', '/var/samba/.')

# ファイルを受信する(サーバ → ローカル)
# *等を使ったパターン指定も可能
get('/var/samba/test.json', '.')

一通りの基本操作は上記のコードでカバーできていると思います。

コマンドの実行もファイル転送もとてもシンプルに書くことができます。

実行

動作を確認する場合は、fabコマンドにfabfile.py内の関数名を指定して実行します。

1
fab task1

Python - scp転送を行う

Pythonからscp転送を行ってみます。

scp転送とはssh通信を使ったファイル転送です。

インストール

Pythonからscp転送を行うためには paramikoscp というライブラリをインストールする必要があります。

1
2
pip install paramiko
pip install scp

コード

scp転送を行う最小コードは次のようになります。

11行目では環境に応じて、IPアドレス・ポート番号・ユーザ名・パスワードを設定してください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import scp
import paramiko

with paramiko.SSHClient() as ssh:
# 初回ログイン時に「Are you sure you want to continue connecting (yes/no)?」と
# きかれても問題なく接続できるように。
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# ssh接続する
print('[ssh接続]')
ssh.connect('[IPアドレス]', port=[ポート番号], username='[ユーザ名]', password='[パスワード]')

print('[SCP転送開始]')
# scp clientオブジェクト生成
with scp.SCPClient(ssh.get_transport()) as scp:
#
# SCP送信(ローカル → サーバ)
#
# ・同じファイルがあったら上書きされる。
# ・ディレクトリは指定できない。
scp.put('test.csv', '/var/samba/.')

#
# SCP受信(サーバ → ローカル)
#
# ・同じファイルがあったら上書きされる。
# ・ディレクトリは指定できない。
scp.get('/var/samba/mpv-shot0004.jpg', '.')

SCP送信する場合でも、SCP受信する場合でも、送信先に同じ名称のファイルがあると上書きされるので注意して下さい。

また、ディレクトリを指定することはできないので複数ファイルを送信する場合は、tarコマンドやzipコマンドを使って1ファイルにまとめてからscp転送する必要があります。

Python - ssh接続しコマンドを実行する

Pythonからssh接続を行いコマンドを実行する処理を行ってみます。

pythonからssh通信ができるようになると、複数サーバに同じコマンドを実行できたり、定期的にサーバ情報を取得し問題があったらアラートを発するなど監視ができるようになりとても便利です。

インストール

Pythonからssh接続を行うためには paramiko というライブラリをインストールする必要があります。

1
pip install paramiko

コード

ssh接続しコマンドを実行する最小コードは次のようになります。

9行目では環境に応じて、IPアドレス・ポート番号・ユーザ名・パスワードを設定してください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import paramiko

with paramiko.SSHClient() as ssh:
# 初回ログイン時に「Are you sure you want to continue connecting (yes/no)?」と
# きかれても問題なく接続できるように。
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# ssh接続
ssh.connect('[IPアドレス]', port=[ポート番号], username='[ユーザ名]', password='[パスワード]')

# コマンド実行
stdin, stdout, stderr = ssh.exec_command('ls -al')

# コマンド実行後に標準入力が必要な場合
# stdin.write('password\n')
# stdin.flush()

# 実行結果を表示
for o in stdout:
print('[std]', o, end='')
for e in stderr:
print('[err]', e, end='')

Python - 文字種(数字、アルファベットなど)の判定を行う

コーディングをしていると対象の文字列かどうかを判定する必要がある場合があります。

複雑な判定を行うときは正規表現で判定することになると思いますが、数字かどうか、アルファベットかどうかなど単純な文字列判定であれば標準で用意されている関数で十分です。

Python標準で用意されている文字種判定の関数を一覧にまとめてみました。

メソッド内容
.isalnum()文字列が全て英数文字かどうかを判定。
! や ? などの記号や空白文字が含まれている場合はFalse。
数字が含まれていてもTrue
空文字はFalse。
.isalpha()文字列が全て英文字かどうかを判定。
! や ? などの記号や空白文字が含まれている場合はFalse。
数字がふくまれていたらFalse
空文字はFalse。
.isdigit()文字列が全て数字かどうかを判定。
全角にも対応。
0から9までの数字のみTrue。
+ - (プラスマイナス)はFalse。
.isnumeric()文字列が全て数字かどうかを判定。
全角にも対応。
0から9までの数字とアラビア数字もTrue。
+ - (プラスマイナス)はFalse。
.islower()文字列が全て小文字かどうかを判定。
.isupper()文字列が全て大文字かどうかを判定。
.istitle()文字列がタイトルケース(単語の先頭が大文字)かどうかを判定。
.isspace()文字列が全て空白文字、タブ文字、改行文字のいずれかどうかを判定。
.isidentifier()文字列が変数として使用できるかどうかを判定。
(先頭がアルファベットまたは"_"で始まり、それ以降がアルファベット、数字、"_"のいずれかで埋まっていること)
.isprintable()文字列が全て表示可能な文字かどうかを判定。
空白文字はTrue。
タブ文字や改行文字が含まれていればFalse。