pandas 系列的“Reduce”功能

tpxzln5u  于 12个月前  发布在  其他
关注(0)|答案(5)|浏览(197)

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中将两个列表合并在一起是O(n)时间。我希望pd.Series有一个向量化的方法来更快地执行这个操作。

8oomwypt

8oomwypt1#

值上带有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数据类型可能会消耗掉你从矢量化中获得的所有性能。我在另一个答案中尝试了矢量化算法。

pxq42qpu

pxq42qpu2#

矢量化但速度慢

你可以使用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

bt1cpqcv

bt1cpqcv3#

你可以用business["categories"].str.join('')试试运气,但我猜Pandas使用Python的字符串函数。我怀疑你能比Python提供的更好。

y1aodyip

y1aodyip4#

我用"".join(business["categories"])
它比business["categories"].str.join('')快得多,但仍然比itertools.chain方法慢4倍。我更喜欢它,因为它更具可读性,不需要导入。

x7yiwoj4

x7yiwoj45#

如果有“无”值,则可以先过滤它们

from itertools import chain

my_series = my_df.apply(lambda x: [j for j in x if j != None])
list(chain.from_iterable(my_series.values))

字符串

相关问题