配列のループ(FOR文)
以下のようなデータがある前提です。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.rand(100000).reshape(100000, 1)) print(df.tail()) # 0 # 99995 0.879119 # 99996 0.600798 # 99997 0.324799 # 99998 0.743424 # 99999 0.520695
普通にdf.iterrows()を使ってループする
%%time
a = 0
for index, row in df.iterrows():
a += row[0]
print(a)
# 50045.80276582274
# CPU times: user 6.9 s, sys: 54.8 ms, total: 6.95 s
# Wall time: 7.11 sdf.valuesでNumPy配列でループする
%%time
a = 0
for val in df.values:
a += val
print(a)
# [50045.80276582]
# CPU times: user 175 ms, sys: 5.27 ms, total: 180 ms
# Wall time: 187 msPandasデータフレームに比べると、圧倒的な処理速度です。
df.valuesでNumPy配列でenumerateを使ってループする
%%time
a = 0
for index, val in enumerate(df.values):
a += val
print(a)
# [50045.80276582]
# CPU times: user 176 ms, sys: 4.7 ms, total: 181 ms
# Wall time: 184 ms
enumerateを使っても、パフォーマンスの低下は見られませんでした。誤差の範囲で、逆に早くなっています。
結論
Pandasデータフレームのままループさせると異常に遅くなります。
Pandasのデータを利用する場合は、NumPy配列に変換してからループさせた方が格段に処理が早くなります。
enumerateを使ってindexを取得してもパフォーマンスは落ちませんでした。
ループで配列に値を追加
Pandasデータフレームにappendで要素を追加
%%time
df = pd.DataFrame()
for i in range(1,10000):
df = df.append({0 : i}, ignore_index=True)
print(len(df))
print(df.head())
# 9999
# 0
# 0 1.0
# 1 2.0
# 2 3.0
# 3 4.0
# 4 5.0
# CPU times: user 13.8 s, sys: 104 ms, total: 13.9 s
# Wall time: 14 sリスト型にappendで要素を追加
%%time
data = []
for i in range(1,10000):
data.append(i)
print(len(data))
print(data[:5])
# 9999
# [1, 2, 3, 4, 5]
# CPU times: user 2.36 ms, sys: 356 µs, total: 2.71 ms
# Wall time: 3.18 msPandasデータフレームに比べると、圧倒的な処理速度です。
二次元配列のリスト型にappendで要素を追加
%%time
data = [[]]
for i in range(1,10000):
data.append([i])
print(len(data))
print(data[:5])
# 10000
# [[], [1], [2], [3], [4]]
# CPU times: user 4.86 ms, sys: 1.56 ms, total: 6.42 ms
# Wall time: 6.39 ms一次元に比べて、倍ほどの処理時間を要していますが、Pandasデータフレームに比べるとやはり格段に早いです。
辞書型(dict)にupdateで要素を追加
%%time
data = {}
for i in range(1,10000):
data.update({i : i})
print(len(data))
# 9999
# CPU times: user 5.76 ms, sys: 996 µs, total: 6.76 ms
# Wall time: 6.6 ms
二次元配列のリスト型とパフォーマンスはほとんど変わりません。
Numpyにappendで要素を追加
%%time
data = np.array([])
for i in range(1,10000):
data = np.append(data, i)
print(len(data))
print(data[:5])
# 9999
# [1. 2. 3. 4. 5.]
# CPU times: user 111 ms, sys: 9.94 ms, total: 121 ms
# Wall time: 128 msリストや辞書型に比べると結構かかっていますが、Pandasデータフレームに比べるとやはり格段に早いです。
二次元のNumpyにappendで要素を追加
%%time
data = np.array([[1]])
for i in range(1,10000):
data = np.append(data, [[i]], axis=0)
print(len(data))
print(data[:5])
# 10000
# [[1]
# [1]
# [2]
# [3]
# [4]]
# CPU times: user 91.4 ms, sys: 13.7 ms, total: 105 ms
# Wall time: 102 ms何故か一次元より処理速度が早くなっています。誤差の範囲として、二次元配列でもパフォーマンスは変わりないということにしましょう。
結論
FOR文(ループ)と同じように、リスト型が圧倒的な早さを見せています。
辞書型(dict)はリスト型より倍ほど遅いですが、それでも他より格段に早いです。
処理速度の順位
- リスト型
- 辞書型(dict)
- Numpy
- Pandasデータフレーム*めちゃめちゃ遅いので使わない方がいいですね。

コメント