numpy – ビット演算を行う関数の使い方

目次

概要

NumPy の要素ごとのビット演算を行う関数について解説します。

numpy.invert

要素ごとにビット単位の NOT を計算します。

numpy.invert(x, /, out=None, *, where=True, casting="same_kind", order="K", dtype=None, subok=True[, signature, extobj]) = <ufunc "invert">
引数
名前 デフォルト値
x array_like
整数型とブール型のみが扱われます。
返り値
名前 説明
out 結果。x がスカラである場合、これはスカラです。
In [1]:
import numpy as np


def bin_repr(arr):
    print("decimal", arr)
    if np.isscalar(arr) or arr.ndim == 0:
        print("binary", np.binary_repr(arr, width=arr.itemsize * 8))
    else:
        print("binary", [np.binary_repr(x, width=arr.itemsize * 8) for x in arr])


arr = np.array([1, 2, 3], dtype=np.int8)
bin_repr(arr)

arr2 = np.invert(arr)
bin_repr(arr2)
decimal [1 2 3]
binary ['00000001', '00000010', '00000011']
decimal [-2 -3 -4]
binary ['11111110', '11111101', '11111100']

numpy.bitwise_or

2つの配列に対して、要素ごとにビット単位の OR を計算します。

numpy.bitwise_or(x1, x2, /, out=None, *, where=True, casting="same_kind", order="K", dtype=None, subok=True[, signature, extobj]) = <ufunc "bitwise_or">
引数
名前 デフォルト値
x1, x2 array_like
整数型とブール型のみが扱われます。
返り値
名前 説明
out 結果。x1x2 の両方がスカラである場合、これはスカラです。
In [2]:
arr1 = np.array([1, 2, 3], dtype=np.int8)
arr2 = np.array([15, 6, 17], dtype=np.int8)
bin_repr(arr1)
bin_repr(arr2)

arr3 = np.bitwise_or(arr1, arr2)
bin_repr(arr3)
decimal [1 2 3]
binary ['00000001', '00000010', '00000011']
decimal [15  6 17]
binary ['00001111', '00000110', '00010001']
decimal [15  6 19]
binary ['00001111', '00000110', '00010011']

numpy.bitwise_and

2つの配列に対して、要素ごとにビット単位の AND を計算します。

numpy.bitwise_and(x1, x2, /, out=None, *, where=True, casting="same_kind", order="K", dtype=None, subok=True[, signature, extobj]) = <ufunc "bitwise_and">
引数
名前 デフォルト値
x1, x2 array_like
整数型とブール型のみが扱われます。
返り値
名前 説明
out 結果。x1x2 の両方がスカラである場合、これはスカラです。
In [3]:
arr1 = np.array([1, 2, 3], dtype=np.int8)
arr2 = np.array([15, 6, 17], dtype=np.int8)
bin_repr(arr1)
bin_repr(arr2)

arr3 = np.bitwise_and(arr1, arr2)
bin_repr(arr3)
decimal [1 2 3]
binary ['00000001', '00000010', '00000011']
decimal [15  6 17]
binary ['00001111', '00000110', '00010001']
decimal [1 2 1]
binary ['00000001', '00000010', '00000001']

numpy.bitwise_xor

要素ごとにビット単位の XOR を計算します。

numpy.bitwise_xor(x1, x2, /, out=None, *, where=True, casting="same_kind", order="K", dtype=None, subok=True[, signature, extobj]) = <ufunc "bitwise_xor">
引数
名前 デフォルト値
x1, x2 array_like
整数型とブール型のみが扱われます。
返り値
名前 説明
out 結果。x1x2 の両方がスカラである場合、これはスカラです。
In [4]:
arr1 = np.array([1, 2, 3], dtype=np.int8)
arr2 = np.array([15, 6, 17], dtype=np.int8)
bin_repr(arr1)
bin_repr(arr2)

arr3 = np.bitwise_xor(arr1, arr2)
bin_repr(arr3)
decimal [1 2 3]
binary ['00000001', '00000010', '00000011']
decimal [15  6 17]
binary ['00001111', '00000110', '00010001']
decimal [14  4 18]
binary ['00001110', '00000100', '00010010']

numpy.left_shift

2つの配列に対して、要素ごとに左シフトを計算します。

numpy.left_shift(x1, x2, /, out=None, *, where=True, casting="same_kind", order="K", dtype=None, subok=True[, signature, extobj]) = <ufunc "left_shift">
引数
名前 デフォルト値
x1 array_like of integer type
入力値。
x2 array_like of integer type
x1 に追加するゼロの数. 非負でなければならない。
返り値
名前 説明
out x1 を、ビットを x2 倍左にシフトして返します。x1x2 の両方がスカラならば、これはスカラです。

numpy.left_shift(x1, x2)x1 << x2 と同じです。

In [5]:
arr = np.array([1, 2, 3], dtype=np.uint8)
bin_repr(arr)

arr2 = np.left_shift(arr, 2)
bin_repr(arr2)

arr3 = arr << 2
bin_repr(arr3)
decimal [1 2 3]
binary ['00000001', '00000010', '00000011']
decimal [ 4  8 12]
binary ['00000100', '00001000', '00001100']
decimal [ 4  8 12]
binary ['00000100', '00001000', '00001100']

シフト演算の結果は x2 の型に合わせてアップキャストされるため、期待した値にならない可能性があります。 例えば、np.left_shift(np.uint8(255), 1) の場合、x1numpy.uint8 型、x2numpy.int64 型です。 255 (0b11111111) を1だけ左シフトした場合、254 (0b11111110) になることを期待しますが、x2 に合わせて numpy.uint64 にアップキャストされて 510 (0b111111110) になります。 numpy.uint8 型において、左シフト演算を行いたい場合は x2 の型も揃えるようにしましょう。

In [6]:
# numpy.int64 にアップキャストしてから左シフト演算を行うので 510 になる。
bin_repr(np.left_shift(np.uint8(255), 1))

# numpy.uint8 で左シフト演算を行いたい場合は、`x2` に指定する型も揃えましょう。
bin_repr(np.left_shift(np.uint8(1), np.uint8(2)))
decimal 510
binary 0000000000000000000000000000000000000000000000000000000111111110
decimal 4
binary 00000100

x2 に配列を指定することで、要素ごとにシフト量を設定できます。

In [7]:
arr = np.array([1, 1, 1], dtype=np.uint8)
bin_repr(arr)

arr2 = np.left_shift(arr, np.uint8([1, 2, 3]))
bin_repr(arr2)
decimal [1 1 1]
binary ['00000001', '00000001', '00000001']
decimal [2 4 8]
binary ['00000010', '00000100', '00001000']
In [8]:
arr = np.array(np.uint8(1), dtype=np.uint8)
bin_repr(arr)

arr2 = np.left_shift(arr, np.uint8([1, 2, 3]))
bin_repr(arr2)
decimal 1
binary 00000001
decimal [2 4 8]
binary ['00000010', '00000100', '00001000']

numpy.right_shift

2つの配列に対して、要素ごとに右シフトを計算します。

numpy.right_shift(x1, x2, /, out=None, *, where=True, casting="same_kind", order="K", dtype=None, subok=True[, signature, extobj]) = <ufunc "right_shift">
引数
名前 デフォルト値
x1 array_like, int
入力値。
x2 array_like, int
x1 の右で削除するビット数。
返り値
名前 説明
out x1 を、ビットを x2 倍右にシフトして返します。x1x2 の両方がスカラならば、これはスカラです。

numpy.right_shift(x1, x2)x1 >> x2 と同じです。

In [9]:
arr = np.array([111, 51, 33], dtype=np.uint8)
bin_repr(arr)

arr2 = np.right_shift(arr, 2)
bin_repr(arr2)

arr3 = arr >> 2
bin_repr(arr3)
decimal [111  51  33]
binary ['01101111', '00110011', '00100001']
decimal [27 12  8]
binary ['00011011', '00001100', '00001000']
decimal [27 12  8]
binary ['00011011', '00001100', '00001000']

x2 に配列を指定することで、要素ごとにシフト量を設定できます。

In [10]:
arr = np.array([111, 51, 33], dtype=np.uint8)
bin_repr(arr)

arr2 = np.right_shift(arr, np.uint8([1, 2, 3]))
bin_repr(arr2)
decimal [111  51  33]
binary ['01101111', '00110011', '00100001']
decimal [55 12  4]
binary ['00110111', '00001100', '00000100']
In [11]:
arr = np.array(np.uint8(111), dtype=np.uint8)
bin_repr(arr)

arr2 = np.right_shift(arr, np.uint8([1, 2, 3]))
bin_repr(arr2)
decimal 111
binary 01101111
decimal [55 27 13]
binary ['00110111', '00011011', '00001101']

numpy.packbits

2値配列 (要素が 0, 1 のみの配列) の要素を、uint8 配列のビットに詰め込みます。

numpy.packbits(myarray, axis=None)
引数
名前 デフォルト値
myarray array_like
要素がビットにパックされるべき整数またはブール値の配列。
axis int None
ビットパッキングが行われる次元。none は、平坦化された配列をパッキングすることを意味しません。
返り値
名前 説明
packed uint8型の配列で、その要素は、入力要素の論理値(0または非0)に対応するビットを表します。パッキングされた の形状は入力と同じ次元数を持ちます( axis がNoneでない限り、その場合、出力は1次元になります)。

numpy.packbits

In [12]:
a = np.array([[1, 0, 1],
              [0, 1, 0],
              [1, 1, 0],
              [0, 0, 1]])

b = np.packbits(a, axis=-1)
print(b)
[[160]
 [ 64]
 [192]
 [ 32]]

numpy.unpackbits

uint8配列の要素を2値の出力配列に展開します。

numpy.unpackbits(myarray, axis=None)
引数
名前 デフォルト値
myarray ndarray, uint8 type
入力配列。
axis int None
ビットアンパックが行われる次元。none は、平坦化された配列をアンパックすることを意味しません。
返り値
名前 説明
unpacked 要素は、2値(0 または 1)です。

numpy.unpackbits

In [13]:
a = np.array([[160], [64], [192], [32]], dtype=np.uint8)

b = np.unpackbits(a, axis=-1)
print(b)
[[1 0 1 0 0 0 0 0]
 [0 1 0 0 0 0 0 0]
 [1 1 0 0 0 0 0 0]
 [0 0 1 0 0 0 0 0]]

numpy.binary_repr

入力された数値を2進表現の文字列として返します。

numpy.binary_repr(num, width=None)
引数
名前 デフォルト値
num int
使用できるのは、整数の10進数のみです。
width int None
num が正の場合は返される文字列の長さ、num が負の場合は2の補数の長さで、widthnum が指定された形式で表現されるのに十分なビット数以上であることを条件とする。
返り値
名前 説明
bin num の2進表現、または num の2つの補数。
In [14]:
print(np.binary_repr(160))
print(np.binary_repr(32))
10100000
100000

width でビット幅を指定できます。

In [15]:
print(np.binary_repr(3, width=8))
00000011

コメント

コメントする

目次