note.nkmk.me

Pythonのリストと配列とnumpy.ndarrayの違いと使い分け

Date: 2018-04-15 / tags: Python, リスト, NumPy, pandas
このエントリーをはてなブックマークに追加

Pythonには、組み込み型としてリストlist、標準モジュールとして配列arrayが用意されている。さらに数値計算ライブラリNumPyをインストールすると多次元配列numpy.ndarrayを使うこともできる。

それぞれの違いと使い分けについて説明する。

表で表現されるような二次元データ(列ごとに特徴量の値を持つもの)を扱うのに便利なデータ分析ライブラリpandasについても最後に少し触れる。

スポンサーリンク

リストと配列とnumpy.ndarrayの違い

リスト - list

  • 組み込み型
    • 何もimportせずに使える
  • 異なる型を格納できる
    • リストのリストによって多次元配列を表現することも可能
  • 厳密には配列と異なるが、配列ライクな簡単な処理を行うのであればリストlistで十分な場合が多い
l = ['apple', 100, 0.123]
print(l)
# ['apple', 100, 0.123]

l_2d = [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
print(l_2d)
# [[0, 1, 2], [3, 4, 5], [6, 7, 8]]

print(l_2d[1][1])
# 4

組み込み関数のmax(), min(), sum(), len()を使って、最大値や最小値、合計、平均などを算出する例。len()は要素数を返す関数。

l_num = [0, 10, 20, 30]

print(min(l_num))
# 0

print(max(l_num))
# 30

print(sum(l_num))
# 60

print(sum(l_num) / len(l_num))
# 15.0

for文によるループ処理の例。

l_str = ['apple', 'orange', 'banana']

for s in l_str:
    print(s)
# apple
# orange
# banana

リストの要素の追加や削除については以下の記事を参照。

配列 - array

コンストラクタarray.array()で型コードを指定して生成する。型コードの一覧は公式ドキュメント参照。

型コードと一致しない型の要素は格納できない。

import array

arr_int = array.array('i', [0, 1, 2])
print(arr_int)
# array('i', [0, 1, 2])

arr_float = array.array('f', [0.0, 0.1, 0.2])
print(arr_float)
# array('f', [0.0, 0.10000000149011612, 0.20000000298023224])

# arr_int = array.array('i', [0, 0.1, 2])
# TypeError: integer argument expected, got float

リストと同様の処理が可能。

print(arr_int[1])
# 1

print(sum(arr_int))
# 3

多次元配列 - numpy.ndarray

import numpy as np

arr = np.array([0, 1, 2])
print(arr)
# [0 1 2]

arr_2d = np.array([[0, 1, 2], [3, 4, 5]])
print(arr_2d)
# [[0 1 2]
#  [3 4 5]]

要素ごとに演算をしたり、行列積を求めたりできる。

arr_2d_sqrt = np.sqrt(arr_2d)
print(arr_2d_sqrt)
# [[0.         1.         1.41421356]
#  [1.73205081 2.         2.23606798]]

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

arr_product = np.dot(arr_1, arr_2)
print(arr_product)
# [[ 9 12 15]
#  [19 26 33]]

独断と偏見によるそれぞれの使い分け

いわゆる配列ライクな処理をするのであればリストlistで十分な場合が多い。

標準モジュールarrayは格納する要素の型が制限されているので厳密なメモリ管理が可能だが、特に気にする必要がなければlist、より効率的な数値計算を行いたければnumpy.ndarrayのほうが適当。メモリサイズ、メモリアドレスを必要とするような処理以外に使いどころはない(と思う)。

多次元配列を扱う場合や配列に対する数値計算(科学技術演算)を行う場合はNumPy配列numpy.ndarrayを使う。

コンピュータビジョンライブラリOpenCVや機械学習ライブラリscikit-learnなど多くのライブラリでNumPy配列numpy.ndarrayが使われているので、それらのライブラリを使うと自動的にnumpy.ndarrayを使うことになる。

なお、listnumpy.ndarrayは相互に変換する事が可能。以下の記事を参照。

データ分析ライブラリpandas

表で表現されるような二次元データ(列ごとに特徴量の値を持つもの)に対して統計的な処理を行う場合は、データ分析ライブラリpandasが便利。

pandasでは二次元データをpandas.DataFrameとして扱う。(pandas.Seiriesとして一次元データを扱うことも可能)

pandas.DataFramepandas.Seriesも内部ではnumpy.ndarrayでデータを保持しているが、行・列ごとの操作や表計算ソフトにおけるピボットテーブルのような操作など、データ処理に便利な関数やメソッドが豊富に用意されている。

雰囲気は以下のような感じ。列ごとの平均値を算出したり、属性を指定して集計したりしている。

import pandas as pd

df = pd.read_csv('data/src/sample_pandas_normal.csv', index_col=0)
df['sex'] = ['Female', 'Male', 'Male', 'Male', 'Female', 'Male']
print(df)
#          age state  point     sex
# name                             
# Alice     24    NY     64  Female
# Bob       42    CA     92    Male
# Charlie   18    CA     70    Male
# Dave      68    TX     70    Male
# Ellen     24    CA     88  Female
# Frank     30    NY     57    Male

print(df.mean())
# age      34.333333
# point    73.500000
# dtype: float64

print(df.pivot_table(index='state', columns='sex', aggfunc='mean'))
#          age        point      
# sex   Female  Male Female  Male
# state                          
# CA      24.0  30.0   88.0  81.0
# NY      24.0  30.0   64.0  57.0
# TX       NaN  68.0    NaN  70.0

例のような数値と文字列を含んだデータはNumPyだと扱いが面倒だが、pandasだと非常に簡単。

詳しい使い方などは以下の記事を参照。

スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事