Numpy 2つの配列を比較して重複していない要素を配列にする

前回に引き続き、NumPyについてのちょっと便利な関数を紹介してます。

setdiff1d()

という関数があります。

まずはサンプルです。

import numpy as np

array1 = np.arange(4)
print(array1)

array2 = np.arange(3)
print(array2)

print(np.setdiff1d(array1, array2))

#次のように出力されます
[0 1 2 3]
[0 1 2]
[3]
[0 1 2 3]


[0 1 2]

の差を教えてくれてますね。

ちなみに逆にすると、空の配列が出力されます。

import numpy as np

array1 = np.arange(4)
print(array1)

array2 = np.arange(3)
print(array2)

print(np.setdiff1d(array2, array1))

#次が出力されます。

[0 1 2 3]
[0 1 2]
[]

ちなみに、setdiff1dがあるなら、 setdiff2dがありそうですが、ありません!!

下記のようなやり方でできるようです。(確認はしていません)
https://stackoverflow.com/questions/8317022/get-intersecting-rows-across-two-2d-numpy-arrays

NumPy 0じゃない要素をカウントする

NumPyのことについてこれからちょいちょい書いておこうと思います。

NumPyはNumerical Pythonの略で、データを高密度のデータバッファに格納し、操作を行うための効率的なインターフェース…です。

ディープラーニングをやる上で、numpy使わないことはほぼないと思います。

しかし、今日まで私はNumPyについては

「うーん わからない時にその都度ググればいいかな」

とか思ってたんですが、♪違う違う~ そうじゃなーいー ってことに気が付きました。

っていうのは、次の理由からです。

  • リストなどより、NumPyでデータを扱った方がずっと早い。機械学習などでは、1万回ループするとか普通にありますが、一回のループで1秒遅いと、1万秒遅くなっちゃいます。
  • NumPyでやれることがわかってないと、データの整形とかがうまくできない
  • Pythonについては、意外とまだまだネット上の情報が少ない(日本語)。なので、ググる人のためになるかな~。

そこで、ここではNumPy自身がどう、とかよりも、目的に合わせて、私が便利だな~と思う関数とかを取り上げていこうと思います。

1回目は、ゼロじゃない要素をカウントする、count_nonzero、です。

import numpy as np

np_pieces = np.array([
[1, 0, 0],
[1, 0, 1],
[0, 0, 0]
])

res = np.count_nonzero(np_pieces, axis=0)
print(res)

#次が出力されます。
[2 0 1]
np.count_nonzero(np_pieces, axis =0)

のaxisですが、これは基準にしたい軸の数です。

軸って何?って思いますよね? …。 嫌い…軸……。(ノω・、) ウゥ・・・

とりあえず、2次元配列では、縦が軸が0、横が1です。今回は、np_piecesという配列の、縦方向が0軸で、縦方向に数えていくと、2,0,1、ということです。

何も指定しないと全部通してのゼロじゃない要素を数えてくれます。

import numpy as np

np_pieces = np.array([
[1, 0, 0],
[1, 0, 1],
[0, 0, 0]
])


res = np.count_nonzero(np_pieces)
print(res) 

#次が出力されます。
3

Python assertの使い方

Pythonにassertという宣言があり、こんな使い方ができますという紹介です。

めっちゃ簡単な話ではありますが…。

Pythonのコードを見ていると、ちょいちょいassert出てきて、ほげー と思ってたんですよね。

なんというか、assert はテストコード内で使うというイメージ。

しかし、Pythonでは、致命的なエラーなどを起こした場合、プログラムを止めることができ、しかも、それはデバッグ版だけで起こせるので、開発に便利だよ~ という感じです。

print("before")

a = 1
assert a == 2, "2じゃない"

print("after")

上記を実行すると

before
Traceback (most recent call last):
File "G:/ai_delivery/study12.py", line 4, in
assert a == 2, "2じゃない"
AssertionError: 2じゃない

Process finished with exit code 1


ってなります。

assertのところで終了しているので、print(“after”)は実行されません。

んで、開発の時にデバッグするためのものだよ~ という話なのですが、本番の時にこんなエラー起きたら大変!とか、理由を解明するのも「ええい、面倒!!」ということがあれば、次のようにコマンドラインオプション -Oをつけて実行すればAssertionErrorが出ません。

G:\ai_delivery>python -O study12.py
before
after

これは、大文字のO(オー)です。ゼロじゃないよ。

The package name takuru_php is invalid, it should be lowercase and have a vendor name, a forward slash, and a package name, matching: [a-z0-9_.-]+/[a-z0-9_.-]+

みんな大好きcomposer。

composerはPHPのライブラリの管理ツールです。

公式サイト https://getcomposer.org/

composerはライブラリの依存関係を、composer.jsonというjsonファイルで管理しています。

もちろん、手で書いてもいいんですが、

composer init

とやると、対話形式でこのcomposer.jsonを作ってくれます。

その時に、表示されるエラーがこれ。

The package name takuru_php is invalid, it should be lowercase and have a vendor name, a forward slash, and a package name, matching: [a-z0-9_.-]+/[a-z0-9_.-]+

ま、よく読めばいいんですが、

「パッケージの名前は、パッケージの名前と、あなたの組織の名前をスラッシュ(バックスラッシュじゃないほう。ギターも弾かないほう)でつないで入れてね。」

というエラーです。

えー、ヤダー、組織の名前なんて入れたくないー。と思っちゃいますが、やらないと、先に進めないのでやりましょう。

たとえば、

hogehoge/all-black-org

とかでいいです。

MySQL CASE文でNULL判定

前回

MySQL SELECT時にCASE文で値をわかりやすく出力するサンプル 

でCASE文の話をしましたが、これでNULL判定するときは気を付けましょう。

サンプルは前回と同じく下記のようなデータですが、4番目の null だけ追加しています。下記のテーブルをcallsとします。

id | driver_id | created
1 | 13 | 2018-11-19 11:23:25
2 | 15 | 2018-11-19 11:25:30
3 | 16 | 2018-11-19 11:26:30
4 | null | 2018-11-19 11:26:30

このテーブルからnullでないドライバーIDの場合は、1、そうでない場合は0を返したい場合、いかにも、下記のように判定できそうですが

SELECT
   id, 
CASE
   driver_id WHEN NULL THEN 0 ELSE 1 
END
FROM
calls

なんとこれではダメです。全部、1が返ってきます。

NULL判定は、CASE文の中でしないといけないそうです。

SELECT 
    id, 
CASE 
    WHEN driver_id IS NULL THEN 0 ELSE 1 
END 
FROM 
calls 

これで、ちゃんと driver_id がNULLの時、0になります。