NumPy の参照とコピー

2023/4/1
執筆者:三雲勇二

※本記事は吉政創成株式会社「Python学習とキャリアアップ」より寄稿されたコラムとなります。

NumPy の参照とコピー

みなさん、こんにちは。 エンジニアをしております、三雲と申します。

私はたまにですが初心者にプログラミングについて教えたりすることがあります。 特に Python は人気で、理由として『データ分析』が簡単に行えるところで興味を持たれる方が多いようです! データ分析というと少し難しそうに感じるかもしれませんが、Python を使うと思ったよりも簡単に行なえます。 この機会に試してみてはいかがでしょうか?

今回は紙書籍版『Pythonによるあたらしいデータ分析の教科書 第2版(翔泳社)』では、p.102 〜 p.105 の部分になります。

テーマは「NumPy の参照とコピー」です。

せっかくですので私も初心に戻り、新人エンジニアやこれからエンジニアを目指している方の「Python でデータ分析を勉強してみよう!」という視点で、分かりやすい記事になればと思います。 どうぞよろしくお願いいたします。

そもそも NumPy とは

NumPy は Python の数値計算のためのライブラリであり、高度な数値計算機能を提供しています。 NumPy の主な機能は、多次元配列(ndarray)オブジェクトをサポートすることで、これにより数値データの効率的で高速な操作を可能にします。

少し難しい言い回しになってしまいましたが、Python のリストより高度な計算が素早く行えるライブラリということみたいです。

NumPy のもう一つの特徴として、多くの Python のライブラリの基礎部分として使用されるため、他のライブラリと一緒にインストールされることが多いです。それほど非常に便利なパッケージなので、Python でプログラミングする方は NumPy の使い方を覚えておいて損はないです。

NumPy は pip でインストールできます。

『Pythonによるあたらしいデータ分析の教科書 第2版(翔泳社)』で使用するバージョンは p.50 にあるとおりのものを指定しましょう。

バージョンによって、使用できるメソッドや引数など変更がある場合がありますので、書籍通りのバージョンをインストールすることが重要です。

書籍通りに動かない場合、よくよく調べてみると「書籍のバージョンと異なるバージョンがインストールされていたことが原因だった」というケースもありますので、ご注意ください。

pip install numpy==1.22.4

NumPy を使うにはパッケージをインポートしておく必要がありますので、忘れずにしておきましょう。

import numpy as np

Python の『参照』と『コピー』の違いを復習

Python 変数に値を代入する際に、参照が作成される場合と、値のコピーが作成される場合とがあります。改めて確認してみましょう。

まず、『参照』について確認しましょう。

少し難しい説明になってしまいますが、参照とは変数に代入されたオブジェクトのメモリ上のアドレスを指します。つまり、参照を持つ変数は、そのオブジェクトのメモリ上の場所を示しているだけで、そのオブジェクト自体を保持しているわけではありません。

以下のコードを例にあげます。

a = [1, 2, [3, 4, 5]]
b = a

この場合、変数 b は変数 a が指すリストオブジェクトのメモリ上の場所を指す参照を持っています。 つまり、a と b は同じオブジェクトを指しています。 したがいまして、a または b のどちらかを変更すると変更内容が両方の変数に反映されます。

次に、『コピー』について確認しましょう。

こちらも少し難しい説明になってしまいますが、コピーとは変数に代入されたオブジェクトを複製して新しいオブジェクトを作成することを指します。

つまり、コピーを持つ変数は、別のメモリ上のオブジェクトを保持しています。Python では、浅いコピーと深いコピーと呼ばれる2種類のコピーがあります。

『浅いコピー』とは、オブジェクトのコピーを作成しますが、コピーされたオブジェクトの内部に含まれる他のオブジェクトについては、参照がコピーされます。したがって、浅いコピーを持つ変数は、コピーされたオブジェクト自体を保持していますが、その内部に含まれるオブジェクトについては、元のオブジェクトと同じメモリ上の場所を指しています。

以下のコードを例にあげます。

a = [1, 2, [3, 4, 5]]
b = a.copy()

この場合、変数 b は変数 a をコピーしますが、[3, 4, 5] (この部分を仮に c とする) のリスト部分は参照として複製されます。

つまり、a と b は異なるリストオブジェクトを指し示していますが、c の部分は参照となるため共有されてしまいます。

『深いコピー』とは、オブジェクトのコピーをすべて作成します。通常のコピーとしてイメージしやすいのはこの動作かと思います。

以下のコードを例にあげます。

a = [1, 2, [3, 4, 5]]
b = copy.deepcopy(a)

この場合、変数 b は変数 a 全体をコピーします。なお、変数に代入された値の参照を作成することを「参照渡し」と呼び、コピーを作成することを「値渡し」と呼ぶこともあります。

NumPy の参照とコピー

NumPy モジュールでは、参照やコピーはどの様になっているのでしょうか。

reval メソッドと flatten メソッドがあるので試してみましょう。

import numpy as np

a = np.array([[11, 12, 13], [21, 22, 23]])
b = a.ravel()
c = a.flatten()

同じ結果が返ってきました。

# b : reval()
array([11, 12, 13, 21, 22, 23])

# c : flatten()
array([11, 12, 13, 21, 22, 23])

では、元の a 配列を操作してみます。

a[0][1] = 123

今度は結果が変わりました。

# b : reval()
array([11, 123, 13, 21, 22, 23])

# c : flatten()
array([11, 12, 13, 21, 22, 23])

reval メソッドは参照され、flatten メソッドはコピーされていました。 なお、NumPy では flatten メソッドは深いコピーとして設定されています。

今回のまとめ

Python の基礎の復習まとめです。Python のコピーには次のものがあります。

  • 参照:値を持っている場所をコピーする
  • コピー:値自体をコピーする
    浅いコピー:コピーされた内部のオブジェクトは参照がコピーされる
    深いコピー:すべての内容がコピーされる

今回 NumPy で使用したメソッドと、参照とコピーの関係は次のとおりです。

  • 参照:reval メソッド
  • 浅いコピー:(今回該当なし)
  • 深いコピー:flatten メソッド

参照とコピーの選び方ですが、基本的に参照のほうが高速かつメモリの使用量が少ないです。コピーをしなければならない場合は、範囲を絞り込んで小さくコピーするなど考えると、処理速度が早くなると思います。参照とコピーの違いをきちんと把握して、NumPy を高速に正しく使い分けられるようになりたいものです。

今回のコラムはいかがでしたでしょうか?インターネット・アカデミーは、Python講座が充実しています。Python認定スクールにもなっているため質の高い知識を得ることができ、基礎学習の先にあるそれぞれの目標を目指していくためには良い場所となります。ご興味ある方は各講座のページを覗いてみてください。

Pythonが学べる講座

この記事の執筆者

エンジニア 三雲勇二

デジタル人材育成・助成金のお役立ち資料をダウンロード

デジタル人材育成や助成金活用のお役立ち資料などをまとめてダウンロードしていただけます。コンサルタントへの無料相談をご希望の方はこちらからお問い合わせください。

たとえばこんな相談ができます
  • DX人材の育成&事例紹介 リスキリングのロードマップ付き
  • デジタル人材育成に使える助成金制度
  • デジタルスキル標準 役割別おすすめ講座
資料ダウンロードはこちら
会社名必須
部署名必須
お名前必須
電話番号必須
メールアドレス必須

個人情報の利用目的についてご同意いただいた場合のみ、「同意して進む」を押してください。

このページの上へ