pandasのmean関数を利用する処理と、利用しない場合の速度比較

データ分析では定番のPython/Pandasですが、いろいろ便利な関数が最初から用意されています。以下はその一例。

  • sum(): 各列の合計値を計算します。
  • mean(): 各列の平均値を計算します。
  • median(): 各列の中央値を計算します。
  • max(): 各列の最大値を計算します。
  • min(): 各列の最小値を計算します。
  • std(): 各列の標準偏差を計算します。

ふと、関数を使う場合と使わない場合では、どの程度の差があるのか知りたくなったので、簡単な比較をしました。とりあえずmean関数だけ。

 

準備

数値集計用に適当なデータフレームを用意します。今回は1000万行×10列のデータフレームを作成。値として8桁のランダムな数字を入れたものにしました。


import pandas as pd
import numpy as np

# テスト用に1000万行×10列のデータフレームを作成。値として8桁のランダムな数字を入れる
df = pd.DataFrame(np.random.randint(10000000, 99999999, size=(10000000, 10)), columns=list('abcdefghij'))

print(df)        
    
平均値を求める

pandasのmean関数を使って、全てのセルの平均値を求めます。


# mean関数で全セルの平均を求める

import pandas as pd
import time

# 処理開始時間を記録する
start_time = time.time()

print("mean関数で全セルの平均を求める")

print((df['a'].mean() + df['b'].mean() + df['c'].mean() + df['d'].mean() + df['e'].mean() + df['f'].mean() + df['g'].mean() + df['h'].mean() + df['i'].mean() + df['j'].mean())/10)

# 処理終了時間を記録する
end_time = time.time()

# 処理時間を計算する
elapsed_time = end_time - start_time

# 処理時間と出力を表示する
print("処理時間:{:.3f}秒".format(elapsed_time))
    

同様に、mean関数を使わずに、全てのセルの平均値を求めてみます。


# mean関数を使わずに全セルの平均を求める

import pandas as pd
import time

# 処理開始時間を記録する
start_time = time.time()

sum = 0
for column in df:
    for value in df[column]:
        sum += value

        
print("mean関数を使わずに全セルの平均を求める")

print(sum/(df.shape[0]*df.shape[1]))

# 処理終了時間を記録する
end_time = time.time()

# 処理時間を計算する
elapsed_time = end_time - start_time

# 処理時間と出力を表示する
print("処理時間:{:.3f}秒".format(elapsed_time))
    
結果

mean関数だと0.613秒に対して、使わないほうは14.148秒と、約23倍ほどmean関数のほうが速いですね。使わないほうは for文で回しているので明らかに遅そうなコードですけど。。。

ほかにもapplyメソッドとか、swifterの利用とか、いろいろ速く動かす方法がpandasにはあるそうです。