0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Python3 / numpy] pandasで並列演算するよりも、frompyfuncが高速?(でも不便だった)

Last updated at Posted at 2020-02-29

Environment

version
OS CentOS7
python 3.8.1
pandas 1.0.1
numpy 1.18.1

概要

結論を一言でいうと、使いどころは微妙でした
pandasの並列演算をnumpy.frompyfunc()で置き換えようとした時の記録です。

経緯

とある開発中、pandasで並列演算していた部分を他メソッドからも使い回して呼びたくなり、numpy.frompyfunc()を使った。

ソースの変更内容を簡略化すると、こんな感じ。

import numpy as np
import pandas as pd

# 元々の処理 - pandasによる並列演算を使った処理
def intercomparison_between_dataframes_old(...):
    # 略 ...
    y_exceed_x_series = df1['x'] < df2['y']
    return y_exceed_x_series 

# 書き換え後 - frompyfuncによる処理
def intercomparison_between_dataframes_new(...):
    y_exceed_x = np.frompyfunc(compare, 2, 1)
    y_exceed_x_series = y_exceed_x(df1['x'], df2['y'])
    retutn y_exceed_x_series 

def compare(x, y):
    return x < y


# ※注
#   書き換え前と書き換え後では、処理結果が若干異なる
#
intercomparison_between_dataframes_old(...)

0    False
1    False
2    False
dtype: bool <-

intercomparison_between_dataframes_new(...)

0    False
1    False
2    False
dtype: object <- 速いけど dtype  object になってた

こうすると何が嬉しいかというと、compare()メソッドを呼び出せすことで、比較ロジックだけを使い回すことができる。

Series同士の並列計算ではなく、1対1で比較したいこともあるのです(←当初の目的)
ほ、本当は引数が6個もある複雑な比較処理なんだからね!(>д<;)

速度を測ってみた

この処理変更によって速度が低下しないか心配だったので、念のため以下の記事の方法で速度測定してみた。

【Python】処理にかかる時間を計測して表示

結果

old_dealtelapsed_time が元々の処理の処理時間
new_dealtelapsed_time が書き換え後処理の処理時間

image.png

「え、 pandasよりfrompyfuncの方が速い じゃん♪(^^*)ラッキー」

処理時間が約7分の1になりました。
想定外の収穫でした。

ちょっと気が早いですが、
「もう並列演算は全部 frompyfunc でいいんじゃないか....(`・д´・;)」
と思ってしまいました。

ところが...

更なる調査で分かったこと

処理結果を調べていて分かったことがあった。

frompyfuncに渡すメソッドの戻り値が2個(以上)の時、戻り値の型がタプル(tupple)になる。

たとえば今回の例でいえば、compare()メソッドの戻り値が2個だったとしたら戻り値がこんな感じになる

>>> intercomparison_between_dataframes_new(...)

(0            True
1            False
2            True
3            False
4            False
          ...   
1553    True
1554    True
1555    True
1556    False
1557    True
Length: 1558, dtype: object, 0           True
1           False
2           True
3           False
4           True
         ...   
1553    True
1554    False
1555    False
1556    True
1557    False
Length: 1558, dtype: object) <- tupple かよぉ....

numpyのメソッドだから二次元のndarrayを返してくれると思ったのに...

frompyfunc()に渡すメソッドの戻り値が1個の時しか、速度改善は望めなさそう。

もし使うとしたら

  • frompyfunc()に渡すメソッドの戻り値が1個ならそこそこ使えそう。

もしかしたら...
処理によっては速度に大差なかったり、逆にfrompyfuncの方が遅いこともあるかもしれない。
とはいえ、結構な差がついているので、基本的にはfrompyfuncの方が速そう。

実際に簡単な処理でも調査したら追記しようと思う。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?