web-dev-qa-db-ja.com

シリーズの「リデュース」機能

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_がこれをより高速に実行するベクトル化された方法を持っていることを願っています。

22
hlin117

値に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

このデータセットの場合、chainingは約68倍高速です。

ベクトル化?

ベクトル化は、ネイティブのNumPyデータ型がある場合に機能します(パンダは結局、データにNumPyを使用します)。シリーズにはすでにリストがあり、結果としてリストが必要なため、ベクトル化によって速度が向上することはまずありません。標準のPythonオブジェクトとpandas/NumPyデータ型の間の変換は、ベクトル化から得られるすべてのパフォーマンスを使い果たす可能性があります。別の答えでアルゴリズムをベクトル化しようと試みました。

19
Mike Müller

ベクトル化されるが遅い

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
2
Mike Müller

あなたはbusiness["categories"].str.join('')で運を試すことができますが、PandasはPythonの文字列関数を使用していると思います。 Pythonがすでに提供しているものをもっと上手に使えるとは思えません。

0
ssm

"".join(business["categories"])を使用しました

business["categories"].str.join('')よりはるかに高速ですが、itertools.chainメソッドよりも4倍遅くなります。読みやすく、インポートが不要なため、こちらを選択しました。