pandasシリーズのreduce
の類似物はありますか?
たとえば、map
のアナログは pd.Series.apply ですが、reduce
のアナログは見つかりません。
私のアプリケーションは、pandas一連のリスト:
_>>> business["categories"].head()
0 ['Doctors', 'Health & Medical']
1 ['Nightlife']
2 ['Active Life', 'Mini Golf', 'Golf']
3 ['Shopping', 'Home Services', 'Internet Servic...
4 ['Bars', 'American (New)', 'Nightlife', 'Loung...
Name: categories, dtype: object
_
以下のように、reduce
を使用して一連のリストをマージしたいと思います。
_categories = reduce(lambda l1, l2: l1 + l2, categories)
_
しかし、Pythonでは2つのリストをマージするのがO(n)
時間であるため、これには恐ろしい時間がかかります。 _pd.Series
_がこれをより高速に実行するベクトル化された方法を持っていることを願っています。
itertools.chain()
を使用これはより速くなる可能性があります:
from itertools import chain
categories = list(chain.from_iterable(categories.values))
from functools import reduce
from itertools import chain
categories = pd.Series([['a', 'b'], ['c', 'd', 'e']] * 1000)
%timeit list(chain.from_iterable(categories.values))
1000 loops, best of 3: 231 µs per loop
%timeit list(chain(*categories.values.flat))
1000 loops, best of 3: 237 µs per loop
%timeit reduce(lambda l1, l2: l1 + l2, categories)
100 loops, best of 3: 15.8 ms per loop
このデータセットの場合、chain
ingは約68倍高速です。
ベクトル化は、ネイティブのNumPyデータ型がある場合に機能します(パンダは結局、データにNumPyを使用します)。シリーズにはすでにリストがあり、結果としてリストが必要なため、ベクトル化によって速度が向上することはまずありません。標準のPythonオブジェクトとpandas/NumPyデータ型の間の変換は、ベクトル化から得られるすべてのパフォーマンスを使い果たす可能性があります。別の答えでアルゴリズムをベクトル化しようと試みました。
NumPyのconcatenate
を使用できます。
import numpy as np
list(np.concatenate(categories.values))
ただし、Pythonオブジェクトが既に存在するため、リストがあります。そのため、ベクトル化ではPythonオブジェクトとNumPyデータ型を切り替える必要があります。これにより、処理が遅くなります。
categories = pd.Series([['a', 'b'], ['c', 'd', 'e']] * 1000)
%timeit list(np.concatenate(categories.values))
100 loops, best of 3: 7.66 ms per loop
%timeit np.concatenate(categories.values)
100 loops, best of 3: 5.33 ms per loop
%timeit list(chain.from_iterable(categories.values))
1000 loops, best of 3: 231 µs per loop
あなたはbusiness["categories"].str.join('')
で運を試すことができますが、PandasはPythonの文字列関数を使用していると思います。 Pythonがすでに提供しているものをもっと上手に使えるとは思えません。
"".join(business["categories"])
を使用しました
business["categories"].str.join('')
よりはるかに高速ですが、itertools.chain
メソッドよりも4倍遅くなります。読みやすく、インポートが不要なため、こちらを選択しました。