NumPyの`resize`の使い方 – 配列の形状を変更する(要素の追加・削除あり)

NumPyは、Python数値計算を効率的に行うためのライブラリです。配列の形状を操作する機能が豊富に用意されています。この記事では、配列の形状を変更する関数の一つであるresizeの基本的な使い方について解説します。reshapeとは異なり、resizeは配列の要素数を変更できる点が特徴です。

numpy.resizendarray.resize の違い

resizeには、numpy.resize()という関数と、NumPy配列オブジェクトのメソッドであるndarray.resize()の2種類が存在します。両者は似ていますが、動作に重要な違いがあります。

機能 numpy.resize (関数) ndarray.resize (メソッド)
操作対象 元の配列は変更せず、新しい配列を返す 元の配列を直接変更する (in-place)
戻り値 新しい形状の配列 None
要素追加時の値 元の配列の要素を繰り返して埋める 0で埋める
他からの参照 影響なし 他の変数から参照されている場合、エラーが発生することがある

一般的に、元のデータを保持したまま新しい形状の配列を得たい場合はnumpy.resize()を、元の配列そのものを変更したい場合はndarray.resize()を使用します。

numpy.resize の基本的な使い方

numpy.resize(a, new_shape)は、指定した配列anew_shapeで指定した形状に変更した新しい配列を返します。

配列を大きくする場合(要素の追加)

新しい形状が元の配列より大きい場合、元の配列の要素が繰り返されて新しい要素が埋められます。

import numpy as np

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

# 配列aを(2, 3)の形状に変更
b = np.resize(a, (2, 3))

print(b)

出力

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

この例では、bの2行目の要素が、aの要素[1, 2, 3]の繰り返しで埋められています。

配列を小さくする場合(要素の削除)

新しい形状が元の配列より小さい場合、末尾の要素が切り捨てられます。

import numpy as np

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

# 配列aを要素数3の1次元配列に変更
b = np.resize(a, 3)

print(b)

出力

[1 2 3]

ndarray.resize の基本的な使い方

a.resize(new_shape)は、配列aそのものの形状を変更します。戻り値はない(None)ため、新しい変数に代入する使い方をしません。

配列を大きくする場合(要素の追加)

新しい形状が元の配列より大きい場合、新しい要素は0で埋められます。これはnumpy.resizeの挙動と異なる点です。

import numpy as np

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

# 配列a自体の形状を(2, 3)に変更
a.resize((2, 3))

print(a)

出力

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

2行目の要素が0で埋められていることがわかります。

配列を小さくする場合(要素の削除)

新しい形状が元の配列より小さい場合、numpy.resizeと同様に末尾の要素が切り捨てられます。

import numpy as np

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

# 配列a自体の形状を要素数4の1次元配列に変更
a.resize(4)

print(a)

出力

[1 2 3 4]

ndarray.resize の注意点

ndarray.resizeは、他の変数から参照されていない場合にのみ使用できます。もし他の変数が同じ配列を参照している場合、ValueErrorが発生します。

import numpy as np

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

# bがaを参照している
b = a

# aの形状を変更しようとするとエラーが発生する
# a.resize((2, 3))
# ValueError: cannot resize an array that has been referenced...

このチェックは、意図しない副作用を防ぐためのものです。どうしてもリサイズしたい場合は、引数refcheck=Falseを指定することで強制的に実行できますが、推奨されません。

resizereshape の違い

resizeと似た機能を持つ関数にreshapeがありますが、その役割は明確に異なります。

機能 resize reshape
素数の変更 可能 不可能
用途 要素の追加・削除を伴う形状変更 素数を変えずに形状のみ変更

reshapeは、元の配列の要素数を維持したまま、形状(次元や各次元の要素数)を変更します。そのため、変更前と変更後で要素数が一致している必要があります。

import numpy as np

a = np.arange(6) # array([0, 1, 2, 3, 4, 5])

# reshapeは要素数が同じ範囲でのみ可能
b = a.reshape((2, 3))
print(b)
# [[0 1 2]
#  [3 4 5]]

# 要素数が異なる形状へのreshapeはエラーになる
# a.reshape((3, 3))
# ValueError: cannot reshape array of size 6 into shape (3,3)

# resizeは要素数が異なっても動作する
c = np.resize(a, (3, 3))
print(c)
# [[0 1 2]
#  [3 4 5]
#  [0 1 2]]

まとめ

numpy.resizeは、配列の要素数を変更して形状を再定義するための関数です。

  • 新しい配列として結果を得たい場合はnumpy.resize()を使用します。要素が不足する場合は元の配列の要素が繰り返されます。
  • 元の配列を直接変更したい場合はndarray.resize()を使用します。要素が不足する場合は0で埋められます。
  • 素数を変えずに形状だけを変更したい場合はreshape()を使用します。

これらの関数の違いを理解し、目的に応じて適切に使い分けることで、データ処理をより柔軟に行うことができます。

NumPyの「flatten」「ravel」の使い方と使い分け – 配列を1次元化(平坦化)する

Python数値計算ライブラリNumPyには、多次元配列を1次元配列に変換(平坦化)するためのflattenravelという2つのメソッドがあります。どちらも似た機能を提供しますが、いくつかの違いがあります。この記事では、flattenravelの基本的な使い方と概要を説明し、それらの違いと使い分けについて解説します。

1. flatten の概要と基本的な使い方

概要

ndarray.flatten()は、多次元配列のコピーを1次元配列として返します。元の配列は変更されません。

基本的な使い方

import numpy as np

# 2次元配列を作成
arr2d = np.array([[1, 2, 3], [4, 5, 6]])
print(f"Original array:\n{arr2d}")

# flattenを使って1次元化 (コピーが返される)
arr1d_flatten = arr2d.flatten()
print(f"flatten: {arr1d_flatten}")

# flattenで作成した配列を変更しても、元の配列は変わらない
arr1d_flatten[0] = 100
print(f"flatten (modified): {arr1d_flatten}")
print(f"Original array after modification:\n{arr2d}")

出力

Original array:
[[1 2 3]
 [4 5 6]]
flatten: [1 2 3 4 5 6]
flatten (modified): [100 2 3 4 5 6]
Original array after modification:
[[1 2 3]
 [4 5 6]]

メモリレイアウトの指定 (order)

order引数を使うと、多次元配列を1次元化する際のメモリ上の配置順序を指定できます。 'C'(C言語スタイル)を選ぶと行優先、'F'(Fortranスタイル)を選ぶと列優先になります。デフォルトは'C'です。

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

arr1d_flatten_c = arr2d.flatten(order='C')  # Cスタイル(行優先) デフォルト
arr1d_flatten_f = arr2d.flatten(order='F')  # Fortranスタイル(列優先)

print(f"flatten (order='C'): {arr1d_flatten_c}")
print(f"flatten (order='F'): {arr1d_flatten_f}")

出力

flatten (order='C'): [1 2 3 4 5 6]
flatten (order='F'): [1 4 2 5 3 6]

2. ravel の概要と基本的な使い方

概要

ndarray.ravel()は、多次元配列を1次元配列として返します。flattenとは異なり、ravelは可能な限り元の配列のビューを返そうとします。(ビューとは、元の配列のデータを共有する別の配列のことです。ビューを変更すると、元の配列も変更されます。) ただし、メモリレイアウトによってはコピーが返される場合もあります。

基本的な使い方

import numpy as np

# 2次元配列を作成
arr2d = np.array([[1, 2, 3], [4, 5, 6]])
print(f"Original array:\n{arr2d}")

# ravelを使って1次元化 (可能な限りビューが返される)
arr1d_ravel = arr2d.ravel()
print(f"ravel: {arr1d_ravel}")

# ravelで作成した配列(ビュー)を変更すると、元の配列も変更される
arr1d_ravel[0] = 100
print(f"ravel (modified): {arr1d_ravel}")
print(f"Original array after modification:\n{arr2d}")

出力

Original array:
[[1 2 3]
 [4 5 6]]
ravel: [1 2 3 4 5 6]
ravel (modified): [100 2 3 4 5 6]
Original array after modification:
[[100 2 3]
 [4 5 6]]

上記の例では、arr1d_ravelarr2d のビューなので、arr1d_ravel への変更が arr2d にも反映されています。

メモリレイアウトの指定 (order)

flattenと同様に、order引数でメモリレイアウトを指定できます。

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

arr1d_ravel_c = arr2d.ravel(order='C')  # Cスタイル(行優先) デフォルト
arr1d_ravel_f = arr2d.ravel(order='F')  # Fortranスタイル(列優先)

print(f"ravel (order='C'): {arr1d_ravel_c}")
print(f"ravel (order='F'): {arr1d_ravel_f}")

出力

ravel (order='C'): [1 2 3 4 5 6]
ravel (order='F'): [1 4 2 5 3 6]

order='F'を指定した場合や、配列がFortran順序で連続している場合など、ravelはビューではなくコピーを返すことがあります。 ビューが欲しいのかコピーが欲しいのか明確でない場合は、ravelの戻り値に対してbase属性をチェックすることで、それがビューなのかコピーなのかを判別できます。ビューであればbase属性は元の配列を指し、コピーであればNoneを返します。

arr = np.array([[1, 2], [3, 4]], order='F')
arr1d_ravel = arr.ravel()
print(arr1d_ravel.base is arr) # False コピーが返された
print(arr1d_ravel.base is None) # False コピーの場合でもNoneとは限らない

arr = np.array([[1, 2], [3, 4]], order='C')
arr1d_ravel = arr.ravel()
print(arr1d_ravel.base is arr) # True ビューが返された

flattenravel の違い

機能 flatten ravel
戻り値 常にコピーを返す 可能な限りビューを返す(メモリレイアウトによってはコピーを返す)
元の配列への影響 元の配列は変更されない ビューが返された場合、ビューの変更は元の配列に影響する
メモリ使用量 コピーを作成するため、メモリ使用量が増える可能性がある ビューの場合はメモリ使用量が少ない。ただし、コピーが作成される場合もある
速度 コピーの作成に時間がかかる場合がある 一般的にflattenより高速(特に大きな配列の場合)
order引数 'C', 'F', 'A', 'K' 'C', 'F', 'A', 'K'

flattenravel の使い分け

  • flatten
    • 元の配列を変更したくない場合
    • 1次元化された配列のコピーが必要な場合
  • ravel
    • メモリ効率を優先する場合(不要なコピーを避けたい場合)
    • 1次元化された配列を通じて、元の配列も変更したい場合
    • 速度が重要な場合(特に大きな配列)

まとめ

flattenravelは、どちらもNumPy配列を1次元化するメソッドですが、flattenは常にコピーを返し、ravelは可能な限りビューを返します(ただし、メモリレイアウトによってはコピーを返すこともあります)。メモリ効率や処理速度を意識して使い分けることが重要です。元の配列を変更したくない場合はflatten、変更したい場合やメモリ効率を優先する場合はravelを使用します。

[PR]

現場で使える!NumPyデータ処理入門 機械学習・データサイエンスで役立つ高速処理手法 (AI & TECHNOLOGY) [ 吉田 拓真 ]

RとPythonで学ぶ[実践的]データサイエンス&機械学習【増補改訂版】 [ 有賀友紀、大橋俊介 ]

Pythonプログラミングパーフェクトマスター[最新Visual Studio Code対応 第4版] [ 金城俊哉 ]

NumPyの「reshape」の使い方 – 配列の形状を変更する

NumPyはPython数値計算を行うためのライブラリです。NumPyのreshape関数を使うと、配列の形状を自由に変更できます。この記事では、reshapeの基本的な使い方から、注意点、応用例を解説します。

reshapeとは

reshapeは、NumPy配列の形状(shape)を変更するための関数です。例えば、1次元配列を2次元配列に変換したり、2次元配列を別の形状の2次元配列に変換したりできます。

reshapeの基本的な考え方

  • 元の配列の要素数は変えずに、形状だけを変更する。
  • 新しい形状は、元の配列の要素数と互換性がある必要がある。(要素数が一致する必要がある)

reshapeの基本的な使い方

reshape関数は、np.reshapeまたは配列のメソッドとしてndarray.reshapeの2通りの方法で利用できます。どちらを使っても結果は同じです。

np.reshapeを使う方法

import numpy as np

arr = np.arange(12)  # 0から11までの要素を持つ1次元配列を作成
print("元の配列:", arr)

reshaped_arr = np.reshape(arr, (3, 4))  # 3x4の2次元配列に変形
print("変形後の配列:\n", reshaped_arr)

出力

元の配列: [ 0  1  2  3  4  5  6  7  8  9 10 11]
変形後の配列:
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

ndarray.reshapeを使う方法

import numpy as np

arr = np.arange(12)  # 0から11までの要素を持つ1次元配列を作成
print("元の配列:", arr)

reshaped_arr = arr.reshape((3, 4))  # 3x4の2次元配列に変形
print("変形後の配列:\n", reshaped_arr)

出力

元の配列: [ 0  1  2  3  4  5  6  7  8  9 10 11]
変形後の配列:
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

新しい形状の指定方法

reshapeの引数には、新しい形状をタプルまたは整数で指定します。

  • タプルで指定: arr.reshape((3, 4)) のように、(行数, 列数)のタプルで指定。
  • 整数で指定: arr.reshape(3, 4) のように、行数、列数を直接指定。

どちらの方法でも同じ結果が得られます。

reshapeの注意点

素数の互換性

reshapeで形状を変更する際、元の配列の要素数と新しい形状の要素数が一致している必要があります。一致しない場合はエラーが発生します。

import numpy as np

arr = np.arange(12)

# エラーになる例: 要素数が一致しない
# reshaped_arr = arr.reshape((3, 5))  # ValueErrorが発生

メモリの共有

reshapeは、多くの場合、元の配列のデータのコピーを作成せず、新しい形状のビュー(view)を返します。これは、メモリ効率が良い反面、ビューを変更すると元の配列も変更される可能性があることを意味します。

import numpy as np

arr = np.arange(12)
reshaped_arr = arr.reshape((3, 4))

reshaped_arr[0, 0] = 100  # reshaped_arrの要素を変更
print("元の配列:", arr)  # arrも変更されている

出力

元の配列: [100   1   2   3   4   5   6   7   8   9  10  11]

データのコピーを作成したい場合は、copyメソッドを使用します。

import numpy as np

arr = np.arange(12)
reshaped_arr = arr.reshape((3, 4)).copy()  # コピーを作成

reshaped_arr[0, 0] = 100  # reshaped_arrの要素を変更
print("元の配列:", arr)  # arrは変更されない

出力

元の配列: [ 0  1  2  3  4  5  6  7  8  9 10 11]

reshapeの応用

-1を使った次元の自動計算

reshapeの引数に-1を指定すると、NumPyが自動的にその次元のサイズを計算します。これは、特定の次元のサイズを明示的に指定したくない場合に便利です。

import numpy as np

arr = np.arange(12)

# 列数を4に固定し、行数は自動計算
reshaped_arr = arr.reshape((-1, 4))
print(reshaped_arr)

出力

[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

-1は、一度のreshapeで一つだけ指定できます。

1次元配列への変換 (flatten)

reshape(-1)を使うと、多次元配列を1次元配列に変換できます。これは、flattenメソッドと同じ結果になります。

import numpy as np

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

# reshape(-1)を使用
flattened_arr = arr.reshape(-1)
print("reshape(-1):", flattened_arr)

# flatten()を使用
flattened_arr_method = arr.flatten()
print("flatten():", flattened_arr_method)

出力

reshape(-1): [1 2 3 4 5 6]
flatten(): [1 2 3 4 5 6]

次元を増やす

reshapeを使って、配列の次元を増やすこともできます。例えば、1次元配列を2次元の行ベクトルや列ベクトルに変換できます。

import numpy as np

arr = np.arange(5)
print("元の配列:", arr)

# 行ベクトルに変換 (1x5)
row_vector = arr.reshape((1, -1))
print("行ベクトル:", row_vector)

# 列ベクトルに変換 (5x1)
column_vector = arr.reshape((-1, 1))
print("列ベクトル:", column_vector)

出力

元の配列: [0 1 2 3 4]
行ベクトル: [[0 1 2 3 4]]
列ベクトル: [[0]
 [1]
 [2]
 [3]
 [4]]

まとめ

NumPyのreshapeは配列の形状を柔軟に変更でき、様々な場面で利用します。 reshapeを活用することで、データ分析や機械学習におけるデータの前処理などが効率的に行えます。

[PR]

現場で使える!NumPyデータ処理入門 機械学習・データサイエンスで役立つ高速処理手法 (AI & TECHNOLOGY) [ 吉田 拓真 ]

RとPythonで学ぶ[実践的]データサイエンス&機械学習【増補改訂版】 [ 有賀友紀、大橋俊介 ]

Pythonプログラミングパーフェクトマスター[最新Visual Studio Code対応 第4版] [ 金城俊哉 ]

NumPyの「array」と「asarray」の使い方と違い – リストやタプルをNumPy配列に変換する

Python NumPyのarray関数とasarray関数は、どちらもリストやタプルなどの入力データをNumPy配列(ndarray)に変換する機能を提供します。これらの関数は似ていますが、いくつかの違いがあります。この記事では、arrayasarrayの基本的な使い方と概要を説明し、それらの違い、そして使い分けについて解説します。

1. array の概要と基本的な使い方

概要

np.arrayは、NumPy配列(ndarray)を作成するための基本的な関数です。リスト、タプル、その他の配列状のオブジェクトをNumPy配列に変換します。最大の特徴は、入力がNumPy配列である場合、常に新しい配列(コピー)を作成することです。これにより、元のデータが変更されるのを防ぐことができます。

基本的な使い方

import numpy as np

# リストからNumPy配列を作成
my_list = [1, 2, 3]
arr_from_list = np.array(my_list)
print(f"type: {type(arr_from_list)}, arr: {arr_from_list}")

# タプルからNumPy配列を作成
my_tuple = (4, 5, 6)
arr_from_tuple = np.array(my_tuple)
print(f"type: {type(arr_from_tuple)}, arr: {arr_from_tuple}")

# 既存のNumPy配列から新しいNumPy配列を作成(コピー)
existing_arr = np.array([7, 8, 9])
new_arr = np.array(existing_arr)  # コピーが作成される
new_arr[0] = 10
print(f"existing_arr: {existing_arr}")  # 元の配列は変更されない
print(f"new_arr: {new_arr}")

出力

type: <class 'numpy.ndarray'>, arr: [1 2 3]
type: <class 'numpy.ndarray'>, arr: [4 5 6]
existing_arr: [7 8 9]
new_arr: [10  8  9]

データ型の指定 (dtype)

dtype引数を使って、作成されるNumPy配列のデータ型を指定できます。

my_list = [1, 2, 3]
arr_float = np.array(my_list, dtype=float)
print(arr_float)

arr_int = np.array(my_list, dtype=np.int32)  # 明示的にint32を指定
print(arr_int)

出力

[1. 2. 3.]
[1 2 3]

メモリレイアウトの指定 (order)

order引数を使うと、多次元配列のメモリ上での配置順序を指定できます。 'C'(C言語スタイル)を選ぶと行優先、'F'(Fortranスタイル)を選ぶと列優先になります。デフォルトは'C'です。

arr_c = np.array([[1,2],[3,4]], order='C') # Cスタイル(行優先)
arr_f = np.array([[1,2],[3,4]], order='F') # Fortranスタイル(列優先)

2. asarray の概要と基本的な使い方

概要

np.asarrayは、np.arrayと同様に、入力データをNumPy配列に変換する関数です。ただし、np.asarrayは、入力が既にNumPy配列の場合、特定の条件下ではコピーを作成しません。これにより、不要なメモリ使用を避け、パフォーマンスを向上させることができます。

基本的な使い方

import numpy as np

# リストからNumPy配列を作成
my_list = [1, 2, 3]
arr_from_list = np.asarray(my_list)
print(f"type: {type(arr_from_list)}, arr: {arr_from_list}")

# タプルからNumPy配列を作成
my_tuple = (4, 5, 6)
arr_from_tuple = np.asarray(my_tuple)
print(f"type: {type(arr_from_tuple)}, arr: {arr_from_tuple}")

# 既存のNumPy配列からNumPy配列を作成(コピーは作成されない可能性がある)
existing_arr = np.array([7, 8, 9])
new_arr = np.asarray(existing_arr)  # デフォルトではコピーは作成されない
new_arr[0] = 10
print(f"existing_arr: {existing_arr}")  # 元の配列も変更される
print(f"new_arr: {new_arr}")

出力

type: <class 'numpy.ndarray'>, arr: [1 2 3]
type: <class 'numpy.ndarray'>, arr: [4 5 6]
existing_arr: [10  8  9]
new_arr: [10  8  9]

データ型の指定 (dtype)

np.arrayと同様に、dtype引数でデータ型を指定できます。dtypeが入力と異なる場合は、コピーが作成されます。

my_list = [1, 2, 3]
arr_float = np.asarray(my_list, dtype=float)  # float型に変換(コピーが作成される)
print(arr_float)

existing_arr = np.array([1,2,3])
arr_float2 = np.asarray(existing_arr, dtype=float) # float型に変換(コピーが作成される)
arr_float2[0] = 0.1
print(existing_arr) # もとの配列は変わらない
print(arr_float2)

出力

[1. 2. 3.]
[1 2 3]
[0.1 2.  3. ]

メモリレイアウトの指定(order)

order引数を使うと、多次元配列のメモリ上での配置順序を指定できます。 'C'(C言語スタイル)を選ぶと行優先、'F'(Fortranスタイル)を選ぶと列優先になります。デフォルトは'C'です。 orderが入力と異なる場合は、コピーが作成されます。

arr = np.array([[1, 2], [3, 4]], order='C')
arr_f = np.asarray(arr, order='F') # Fortran orderに変更(コピーが作成される)

コピーを制御するcopy引数(NumPy 1.20以降)

np.asarrayにはcopy引数があり、copy=Trueとすると、入力がNumPy配列であっても常にコピーが作成されるようになります。NumPy 1.20で導入されました。

existing_arr = np.array([1,2,3])
arr_copied = np.asarray(existing_arr, copy=True) # コピーを作成
arr_copied[0] = 4
print(existing_arr) # もとの配列は変わらない
print(arr_copied)

出力

[1 2 3]
[4 2 3]

arrayasarrayの違い

arrayasarrayの最も重要な違いは、入力が既にNumPy配列の場合の挙動です。

  • np.array: 入力がNumPy配列の場合、常に新しい配列(コピー)を作成します。
  • np.asarray: 入力がNumPy配列の場合、原則としてコピーを作成しません。ただし、dtypeorderが入力と異なる場合、またはcopy=Trueが指定された場合はコピーが作成されます。

arrayasarray の使い分け

機能 asarray array
入力がリスト、タプル等 NumPy配列に変換 NumPy配列に変換
入力がNumPy配列 - copy=False(デフォルト)で、dtypeとorderが入力と同じ場合: コピーを作成しない(参照を返す)
- copy=Trueの場合、dtypeやorderが異なる場合: コピーを作成
常にコピーを作成
データ型の指定(dtype) 可能 可能
メモリレイアウトの指定(order) 可能 可能
使用場面 - 既存のNumPy配列の不要なコピーを避けたい場合
- 入力がNumPy配列である保証がない場合(リスト、タプル、またはNumPy配列のいずれかである可能性がある場合)
- 入力データをNumPy配列として扱いたい場合
- 入力に関わらず、常に新しいNumPy配列を作成したい場合
- 元の配列を変更から保護したい場合

まとめ

np.arraynp.asarrayは、どちらもリストやタプルなどをNumPy配列に変換できます。入力が既にNumPy配列の場合、np.arrayは常にコピーを作成しますが、np.asarrayはデフォルトではコピーを作成しません(条件によってはコピーを作成します)。メモリ効率を重視する場合はnp.asarray、元のデータを保護したい場合はnp.arrayといった形で使い分けます。入力がNumPy配列であるかどうかわからない場合や、NumPy配列で統一的に処理したい場合は、np.asarrayを使うのが便利です。

NumPyの「eye」の使い方 – 単位行列を生成する

NumPyのeyeは、単位行列を生成するための関数です。単位行列は、対角成分が1で、それ以外の成分が0の正方行列です。機械学習線形代数の計算でよく利用されます。この記事では、eye関数の基本的な使い方から、identity関数やdiag関数との比較までを解説します。

eyeの基本的な使い方

eye関数は、指定したサイズの単位行列を生成します。

最もシンプルな例

import numpy as np

# 3x3の単位行列を生成
arr = np.eye(3)
print(arr)

このコードでは、np.eye(3)によって、3x3単位行列が生成され、arr変数に格納されます。eye関数はデフォルトでfloat64型の1と0で要素を生成します。

出力

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

行数と列数の指定

eye関数の最初の引数には、生成したい単位行列の行数を指定します。列数を指定することもでき、その場合は第2引数Nに列数を指定します。

# 4x4の単位行列
arr1 = np.eye(4)
print(arr1)

# 2x5の行列(対角成分のみ1)
arr2 = np.eye(2, 5)
print(arr2)

出力

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

対角成分の位置の指定

k引数を使うと、1を配置する対角線の位置を指定できます。デフォルトは0で、これは主対角線(左上から右下への対角線)を意味します。kを正の数にすると対角線が上に、負の数にすると下にずれます。

# 主対角線から1つ上にずらす
arr1 = np.eye(3, k=1)
print(arr1)

# 主対角線から2つ下にずらす
arr2 = np.eye(4, k=-2)
print(arr2)

出力

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

データ型の指定

dtype引数で、配列のデータ型を指定できます。デフォルトはfloat64です。

# int型の単位行列
arr_int = np.eye(2, dtype=int)
print(arr_int)

# complex型の単位行列
arr_complex = np.eye(2, dtype=complex)
print(arr_complex)

出力

[[1 0]
 [0 1]]
[[1.+0.j 0.+0.j]
 [0.+0.j 1.+0.j]]

メモリレイアウトの指定(order)

order引数を使うと、多次元配列のメモリ上での配置順序を指定できます。 'C'(C言語スタイル)を選ぶと行優先、'F'(Fortranスタイル)を選ぶと列優先になります。デフォルトは'C'です。 通常意識する必要はありませんが、特定の計算ライブラリと連携する際に、パフォーマンスに影響することがあります。

# Fortranスタイルの配列
arr_f = np.eye(3, order='F')

identity関数との比較

identity関数も単位行列を生成しますが、eye関数とは異なり、正方行列しか生成できません。また、identity関数はk引数を持たないため、対角線の位置を調整できません。

# 3x3の単位行列を生成
arr = np.identity(3)
print(arr)

出力

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

diag関数との比較

diag関数は、対角成分を指定して配列を生成したり、既存の配列から対角成分を取り出すことができます。eye関数とは異なり、非正方行列を生成したり、対角成分の値を自由に設定できます。

# 対角成分が[1, 2, 3]の配列を生成
arr = np.diag([1, 2, 3])
print(arr)

# 既存の配列の対角成分を取得
arr_diag = np.diag(arr)
print(arr_diag)

出力

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

eye, identity, diag の使い分け

機能 eye identity diag
正方行列の生成
非正方行列の生成 ×
対角線の位置指定 ×
対角成分の値の指定 × ×
  • eye: 単位行列や、対角線の位置をずらした行列を生成する場合。
  • identity: シンプルな単位行列を生成する場合。
  • diag: 対角成分を自由に設定したり、既存の配列から対角成分を取得する場合。

まとめ

NumPyのeye関数は、単位行列やそれに類似した行列を効率的に生成する関数です。identity関数やdiag関数と使い分けることで、さまざまな行列を柔軟に扱えます。

NumPyの「ones」の使い方 – 「1」で初期化された配列を生成する

NumPyは、Python数値計算を行うためのライブラリです。NumPyを使うと、効率的な数値計算に不可欠な多次元配列を簡単に作成・操作できます。この記事では、NumPyで1で初期化された配列を生成するためのones関数の基本的な使い方、そしてones_like関数との使い分けについて解説します。

onesの基本的な使い方

ones関数は、指定した形状(shape)とデータ型(dtype)を持つ、すべての要素が1で初期化された配列を生成します。

最もシンプルな例

import numpy as np

# 形状が(2, 3)の2次元配列を生成
arr = np.ones((2, 3))
print(arr)

このコードでは、np.ones((2, 3))によって、2行3列の2次元配列が生成され、arr変数に格納されます。ones関数はデフォルトでfloat64型の1を生成します。

出力

[[1. 1. 1.]
 [1. 1. 1.]]

形状の指定

ones関数の最初の引数には、生成したい配列の形状をタプルで指定します。

# 5つの要素を持つ1次元配列
arr1 = np.ones(5)
print(arr1)

# 3x4x2の3次元配列
arr2 = np.ones((3, 4, 2))
print(arr2)

出力

[1. 1. 1. 1. 1.]
[[[1. 1.]
  [1. 1.]
  [1. 1.]
  [1. 1.]]

 [[1. 1.]
  [1. 1.]
  [1. 1.]
  [1. 1.]]

 [[1. 1.]
  [1. 1.]
  [1. 1.]
  [1. 1.]]]

データ型の指定

dtype引数で、配列のデータ型を指定できます。デフォルトはfloat64です。

# int型の配列
arr_int = np.ones((2, 2), dtype=int)
print(arr_int)

# complex型の配列
arr_complex = np.ones((2, 2), dtype=complex)
print(arr_complex)

出力

[[1 1]
 [1 1]]
[[1.+0.j 1.+0.j]
 [1.+0.j 1.+0.j]]

メモリレイアウトの指定(order)

order引数を使うと、多次元配列のメモリ上での配置順序を指定できます。 'C'(C言語スタイル)を選ぶと行優先、'F'(Fortranスタイル)を選ぶと列優先になります。デフォルトは'C'です。 通常意識する必要はありませんが、特定の計算ライブラリと連携する際に、パフォーマンスに影響することがあります。

# Fortranスタイルの配列
arr_f = np.ones((2, 3), order='F')

ones_likeの使い方

ones_like関数は、既存の配列と同じ形状とデータ型を持つ、1で初期化された配列を生成します。

# 既存の配列
arr = np.array([[1, 2, 3], [4, 5, 6]])

# arrと同じ形状とデータ型の1で埋められた配列を生成
arr_ones = np.ones_like(arr)
print(arr_ones)

出力

[[1 1 1]
 [1 1 1]]

ones_likeは、既存の配列の形状や型を明示的に指定せずに、それらを引き継いだ新しい配列を作成したい場合に便利です。

onesones_like の使い分け

機能 ones ones_like
新規配列の生成
形状の指定 必要 不要(既存配列から取得)
データ型の指定 可能 不要(既存配列から取得)
  • ones: 配列の形状とデータ型を明示的に指定して、新しい配列を作成する場合
  • ones_like: 既存の配列と同じ形状とデータ型を持つ配列を作成する場合

まとめ

NumPyのonesones_likeは、1で初期化された配列を生成します。onesは形状やデータ型を直接指定するのに対し、ones_likeは既存の配列を基にする点が異なります。これらの関数を使い分けることで、NumPyを使った数値計算を効率的に行えます。

0で初期化された配列を生成するNumpyのzerosについては、下記の記事で解説しています。

pydocument.hatenablog.com

NumPyの「zeros」の使い方 – 「0」で初期化された配列を生成する

NumPyは、Python数値計算を行うためのライブラリです。NumPyを使うと、効率的な数値計算に不可欠な多次元配列を簡単に作成・操作できます。この記事では、NumPyで0で初期化された配列を生成するためのzeros関数の基本的な使い方、そしてzeros_like関数との使い分けについて解説します。

zerosの基本的な使い方

zeros関数は、指定した形状(shape)とデータ型(dtype)を持つ、すべての要素が0で初期化された配列を生成します。

最もシンプルな例

import numpy as np

# 形状が(2, 3)の2次元配列を生成
arr = np.zeros((2, 3))
print(arr)

このコードでは、np.zeros((2, 3))によって、2行3列の2次元配列が生成され、arr変数に格納されます。zeros関数はデフォルトでfloat64型の0を生成します。

出力

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

形状の指定

zeros関数の最初の引数には、生成したい配列の形状をタプルで指定します。

# 5つの要素を持つ1次元配列
arr1 = np.zeros(5)
print(arr1)

# 3x4x2の3次元配列
arr2 = np.zeros((3, 4, 2))
print(arr2)

出力

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

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

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

データ型の指定

dtype引数で、配列のデータ型を指定できます。デフォルトはfloat64です。

# int型の配列
arr_int = np.zeros((2, 2), dtype=int)
print(arr_int)

# complex型の配列
arr_complex = np.zeros((2, 2), dtype=complex)
print(arr_complex)

出力

[[0 0]
 [0 0]]
[[0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j]]

メモリレイアウトの指定(order)

order引数を使うと、多次元配列のメモリ上での配置順序を指定できます。 'C'(C言語スタイル)を選ぶと行優先、'F'(Fortranスタイル)を選ぶと列優先になります。デフォルトは'C'です。 通常意識する必要はありませんが、特定の計算ライブラリと連携する際に、パフォーマンスに影響することがあります。

# Fortranスタイルの配列
arr_f = np.zeros((2, 3), order='F')

zeros_likeの使い方

zeros_like関数は、既存の配列と同じ形状とデータ型を持つ、0で初期化された配列を生成します。

# 既存の配列
arr = np.array([[1, 2, 3], [4, 5, 6]])

# arrと同じ形状とデータ型の0配列を生成
arr_zeros = np.zeros_like(arr)
print(arr_zeros)

出力

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

zeros_likeは、既存の配列の形状や型を明示的に指定せずに、それらを引き継いだ新しい配列を作成したい場合に便利です。

zeroszeros_like の使い分け

機能 zeros zeros_like
新規配列の生成
形状の指定 必要 不要(既存配列から取得)
データ型の指定 可能 不要(既存配列から取得)
  • zeros: 配列の形状とデータ型を明示的に指定して、新しい配列を作成する場合
  • zeros_like: 既存の配列と同じ形状とデータ型を持つ配列を作成する場合

まとめ

NumPyのzeroszeros_likeは、0で初期化された配列を生成します。 zerosは形状やデータ型を直接指定するのに対し、zeros_likeは既存の配列を基にする点が異なります。 これらの関数を使い分けることで、NumPyを使った数値計算を効率的に行えます。

1で初期化された配列を生成するNumpyのonesについては、下記の記事で解説しています。

pydocument.hatenablog.com

NumPyの「linspace」の使い方 – 指定区間を指定個数で等分割した配列を生成する

NumPyは、Python数値計算を行うためのライブラリです。NumPyのlinspace関数を使うと、指定した区間を指定した個数で等分割した数値の配列を簡単に生成できます。この記事では、linspaceの基本的な使い方から、応用的な使い方までを解説します。

linspaceとは?

linspaceは、"linear space"の略で、線形空間を意味します。 指定された開始点と終了点の間を指定された数の要素で等間隔に分割した配列を返します。

linspaceの基本的な使い方

linspace関数は、少なくとも開始点、終了点、要素数の3つの引数を取ります。

最もシンプルな例

import numpy as np

# 0から10までを5等分した配列を生成
data = np.linspace(0, 10, 5)
print(data)

このコードでは、0から10までの範囲を5等分したNumPy配列を生成しています。

出力

[ 0.   2.5  5.   7.5 10. ]

主要な引数

linspace関数は、主に以下の引数を受け取ります。

引数 説明
start 開始点の値 0
stop 終了点の値 10
num 生成する要素の数(デフォルトは50) 5
endpoint True(デフォルト)の場合、終了点を含む。Falseの場合、終了点を含まない True, False
retstep Trueの場合、要素間の間隔も返す True, False
dtype 出力配列のデータ型 int, float

終了点を含まない配列の生成

endpoint引数をFalseに設定することで、終了点を含まない配列を生成できます。

# 0から10までを5等分した配列を生成(10は含まない)
data = np.linspace(0, 10, 5, endpoint=False)
print(data)

出力

[0. 2. 4. 6. 8.]

間隔の取得

retstep引数をTrueに設定すると、生成された配列と要素間の間隔(ステップサイズ)をタプルで返します。

# 0から10までを5等分した配列と間隔を取得
data, step = np.linspace(0, 10, 5, retstep=True)
print("配列:", data)
print("間隔:", step)

出力

配列: [ 0.   2.5  5.   7.5 10. ]
間隔: 2.5

データ型の指定

dtype引数で、出力配列のデータ型を指定できます。デフォルトはfloat64です。

# 0から10までを5等分した整数配列を生成
data = np.linspace(0, 10, 5, dtype=int)
print(data)

出力

[ 0  2  5  7 10]

linspaceの応用例

グラフの描画

linspaceは、グラフのx軸の値を生成する際によく使われます。

import matplotlib.pyplot as plt

# -5から5までを100等分した配列を生成
x = np.linspace(-5, 5, 100)
y = x**2  # xの2乗を計算

plt.plot(x, y)
plt.xlabel("x")
plt.ylabel("y = x^2")
plt.title("Parabola")
plt.grid(True)
plt.show()

このコードは、-5から5までの範囲を100等分したx値に対して、y = x^2のグラフ(放物線)を描画します。

まとめ

NumPyのlinspace関数は、指定した範囲を等間隔に分割した配列を生成するためのシンプルで扱いやすい関数です。グラフの描画、数値シミュレーション、データ分析など、様々な場面で活用できます。

NumPyの「arange」の使い方 – 連番や等差数列の配列を生成する

NumPyはPython数値計算を行うためのライブラリです。NumPyのarange関数は、連番や等差数列を要素とするndarray配列を生成します。この記事では、arangeの基本的な使い方、主要な引数、そして具体的な使用例について解説します。

arangeの基本的な使い方

arangeは、引数で指定された範囲と間隔に基づいて、等間隔の数値を生成します。

最もシンプルな例

import numpy as np

# 0から4までの整数列を生成
arr = np.arange(5)
print(arr)

このコードでは、0から始まり5未満の整数列を生成し、NumPy配列としてarr変数に格納しています。arangeはデフォルトで0から始まり、1ずつ増加する整数を生成します。

出力

[0 1 2 3 4]

arangeの主要な引数

arangeは以下の引数を取ります。

引数 説明
start 数列の開始値を指定します。省略した場合は0になります。 np.arange(2, 10) # 2から始まる
stop 数列の終了値を指定します。この値は数列に含まれません。 np.arange(5) # 5は含まれない
step 数値の間隔を指定します。省略した場合は1になります。 np.arange(0, 10, 2) # 2ずつ増加
dtype 生成される配列のデータ型を指定します。省略した場合は、他の引数から型推論されます。整数、浮動小数点数複素数など、様々なデータ型を指定可能です。 np.arange(5, dtype=float) # float型の配列を生成

始値、終了値、間隔の指定

# 2から始まり、10未満まで、2ずつ増加する数列
arr = np.arange(2, 10, 2)
print(arr)

出力

[2 4 6 8]

浮動小数点数の数列

stepに小数を指定すると、浮動小数点数の数列を生成できます。

# 0から始まり、1未満まで、0.1ずつ増加する数列
arr = np.arange(0, 1, 0.1)
print(arr)

出力

[0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]

データ型の指定

dtypeでデータ型を指定できます。

arr = np.arange(5, dtype=float)
print(arr)

出力

[0. 1. 2. 3. 4.]

arange使用時の注意点

浮動小数点数の誤差

step浮動小数点数を指定した場合、丸め誤差により、要素数が予想と異なる場合があります。

arr = np.arange(0, 1, 0.1)
print(len(arr))  # 10になることを期待
print(arr)

環境にもよりますが出力は次のようになります。

10
[0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]

10が出力されることもあれば、丸め誤差によって、9が出力されることもあります。

arr = np.arange(0, 5, 0.5)
print(len(arr)) # 10になることを期待
print(arr)

出力(例)

9
[0.  0.5 1.  1.5 2.  2.5 3.  3.5 4. ]

浮動小数点数の等差数列を扱う場合は、linspaceの使用も検討してください。

stopの値は含まれない

arangeで生成される数列には、stopで指定した値は含まれません。

arr = np.arange(1, 5)
print(arr)

出力

[1 2 3 4]

linspaceとの比較

linspaceも等間隔の数列を生成する関数ですが、arangeとは引数の指定方法が異なります。

  • arange: 生成する数列の間隔を指定
  • linspace: 生成する数列の素数を指定
# 0から1までを5等分した数列を生成
arr = np.linspace(0, 1, 5)
print(arr)

出力

[0.   0.25 0.5  0.75 1.  ]

linspaceでは最後の値(この場合は1)が含まれます。

まとめ

NumPyのarangeは、連番や等差数列を生成するための関数です。start, stop, step引数を使うことで、柔軟に数列を生成できます。 浮動小数点数の数列を扱う場合は、丸め誤差に注意が必要です。要素数を指定して等間隔の数列を生成したい場合は、linspaceを使用を検討してください。

pydocument.hatenablog.com

NumPyの「loadtxt」「genfromtxt」 の使い方 – テキストファイルから配列を読み込む

NumPyは、Python数値計算を行うためのライブラリです。NumPyを使うと、テキストファイルからデータを読み込んで配列として扱うことが容易になります。この記事では、テキストファイルからデータを読み込むための主要な関数であるloadtxtgenfromtxtの基本的な使い方、違い、そして高度な利用例について解説します。

loadtxtとgenfromtxtの使い分け

どちらもテキストファイルからデータを読み込み、NumPy配列を作成するための関数です。

loadtxtとgenfromtxtの使い分け

シンプルなテキストファイルではloadtxtで十分です。欠損値を含むファイル、構造が複雑なファイルなどは、genfromtxtを使用します。loadtxtと比べ柔軟な処理が可能です。

機能 loadtxt genfromtxt
基本的な読み込み
欠損値の自動処理 ×
欠損値のカスタマイズ ×
ヘッダー行の処理 ×
構造化配列 ×

loadtxtの基本的な使い方

loadtxtは、区切り文字で区切られたシンプルなテキストファイルを読み込むのに適しています。

最もシンプルな例

import numpy as np

# サンプルデータ (data.txt)
# 1 2 3
# 4 5 6
data = np.loadtxt('data.txt')
print(data)

このコードでは、data.txtという名前のファイルからデータを読み込み、NumPy配列としてdata変数に格納しています。loadtxtはデフォルトで空白を区切り文字として認識します。

出力

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

区切り文字の指定

区切り文字はdelimiter引数で指定できます。例えば、カンマ区切りのファイル(data.csv)を読み込むには以下のようにします。

# サンプルデータ (data.csv)
# 1,2,3
# 4,5,6
data = np.loadtxt('data.csv', delimiter=',')
print(data)

特定の列の読み込み

usecols引数を使うと、特定の列だけを読み込めます。例えば、1列目と3列目だけを読み込むには以下のようにします。

# サンプルデータ (data.txt)
# 1 2 3
# 4 5 6

data = np.loadtxt('data.txt', usecols=(0, 2))
print(data)

出力

[[1. 3.]
 [4. 6.]]

コメント行のスキップ

comments引数を使うと、指定した文字で始まる行をコメントとしてスキップできます。デフォルトでは#がコメント文字です。

# サンプルデータ (data_with_comments.txt)
# # これはコメント行です
# 1 2 3
# 4 5 6
data = np.loadtxt('data_with_comments.txt', comments='#')
print(data)

データ型の指定

dtype引数で、読み込むデータの型を指定できます。デフォルトはfloatです。

# サンプルデータ (data.txt)
# 1 2 3
# 4 5 6
data = np.loadtxt('data.txt', dtype=int)
print(data)

出力

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

genfromtxtの基本的な使い方

genfromtxtloadtxtよりも高機能で、欠損値を含むデータや、より複雑な構造のテキストファイルを扱うのに適しています。

最もシンプルな例

import numpy as np

# サンプルデータ (data_with_missing.txt)
# 1 2 3
# 4   6  # 2列目が欠損
data = np.genfromtxt('data_with_missing.txt')
print(data)

出力

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

loadtxtではエラーになるような欠損値を含む場合でも、genfromtxtはデフォルトでnan (Not a Number) で補完して読み込みます。

genfromtxtの主要な引数

genfromtxtloadtxtのすべての機能を備えています。delimiter, usecols, comments, dtypeなどの引数はgenfromtxtでも同様に使用できます。

引数 説明
fname 読み込むファイル名(またはファイルオブジェクト) 'data.csv'
delimiter 区切り文字 ',' (カンマ), '\t' (タブ), ' ' (スペース)
usecols 読み込む列のインデックスを指定 (0, 2, 4) (1列目、3列目、5列目を読み込む)
comments コメントとして扱う文字列の始まりを指定 '#' (デフォルト), '%', '//'
dtype 読み込むデータの型 int, float, str, (int, float, float) (各列の型を個別に指定)
missing_values 欠損値として認識する文字列を指定 ['?', 'N/A', '']
filling_values 欠損値を置き換える値を指定 -999, 0, ''
names Trueにすると、最初の行を列名として扱う。文字列のリストで列名を指定することも可能。 True, ['time', 'value1', 'value2']
skip_header ファイルの先頭からスキップする行数を指定 1 (最初の1行をスキップ), 0 (デフォルト: スキップしない)
skip_footer ファイルの末尾から読み飛ばす行数を指定します。 10(最後の10行を読み飛ばします)

欠損値の扱い

genfromtxtの強力な機能の一つは、欠損値の処理方法を細かく制御できることです。

  • missing_values: 欠損値として認識する文字列を指定します。
  • filling_values: 欠損値を特定の値で置き換えます。
# サンプルデータ (data_with_missing_custom.txt)
# 1,?,3
# 4,5,N/A
data = np.genfromtxt('data_with_missing_custom.txt', delimiter=',', missing_values=['?', 'N/A'], filling_values=-999)
print(data)

出力

[[   1. -999.    3.]
 [   4.    5. -999.]]

この例では、?N/Aを欠損値として認識し、それらを-999で置き換えています。

応用: ヘッダー行のスキップと名前付き配列

genfromtxtは、ヘッダー行を持つファイルや、各列に名前が付いているファイルを扱う際に便利です。

# サンプルデータ (data_with_header.csv)
# Time,Value1,Value2
# 0,1.0,2.0
# 1,3.0,4.0
# 2,5.0,6.0

data = np.genfromtxt('data_with_header.csv', delimiter=',', names=True, skip_header=0)

print(data)
print(data['Time'])
print(data['Value1'])

出力

[(0., 1., 2.) (1., 3., 4.) (2., 5., 6.)]
[0. 1. 2.]
[1. 3. 5.]
  • names=True: 1行目をヘッダーとして扱い、列名として使用します。
  • skip_header=0 : ヘッダー行をスキップする行数を指定します。(今回はスキップしないので0)

これにより、data['Time']のように、列名でデータにアクセスできる構造化配列(structured array)が得られます。skip_headerで指定された行数だけ読み飛ばします。

まとめ

NumPyのloadtxtgenfromtxtは、テキストファイルからデータをNumPy配列に読み込見ます。それぞれの関数の特性を理解し、データの形式や目的に応じて使い分けることで、効率的なデータ処理が可能になります。特に、genfromtxt は、より現実に即した複雑なデータを取り扱う場面で有用です。

現場で使える!NumPyデータ処理入門 機械学習・データサイエンスで役立つ高速処理手法 (AI & TECHNOLOGY) [ 吉田 拓真 ]