Функция "Уменьшить" для серии

Есть ли аналоговый для reduce для серии pandas?

Например, аналоговый для 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)

но это требует ужасающего времени, потому что объединение двух списков вместе - это O(n) время в Python. Я надеюсь, что pd.Series имеет векторизованный способ выполнения этого быстрее.

Ответ 1

С 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 (pandas использует NumPy для своих данных). Поскольку мы уже имеем списки в Серии и хотим, чтобы список был результатом, маловероятно, что векторизация ускорит процесс. Преобразование между стандартными объектами Python и типами данных pandas/NumPy, скорее всего, поглотит всю производительность, которую вы можете получить от векторизации. Я сделал одну попытку векторизации алгоритма в другом ответе.

Ответ 2

Векторизованный, но медленный

Вы можете использовать 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

Ответ 3

Вы можете испытать удачу с помощью business["categories"].str.join(''), но я предполагаю, что Pandas использует строковые функции Pythons. Я сомневаюсь, что вы можете сделать то, что уже предлагает Python.