系列"Reduce"功能



熊猫系列有reduce的模拟吗?

例如,map的模拟是pd。Series.apply,但我找不到任何reduce的模拟。


我的应用是,我有一个熊猫系列列表:

>>> 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 中将两个列表合并在一起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速度提高了约 68 倍。

矢 量化?

当您拥有本机 NumPy 数据类型时,矢量化有效(毕竟 pandas 使用 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 倍。我更喜欢它,因为它更具可读性并且不需要导入。

最新更新