【问题标题】:Custom Vectorization in numpy for string arraysnumpy中用于字符串数组的自定义向量化
【发布时间】:2021-11-25 19:52:09
【问题描述】:

我正在尝试在numpy string arrays 上申请vectorization with custom function

例子:

import numpy

test_array = numpy.char.array(["sample1-sample","sample2-sample"])

numpy.char.array(test_array.split('-'))[:,0]

操作:

chararray([b'sample1', b'sample2'], dtype='|S7')

但是这些都是in-built的功能,有没有其他方法可以实现vectorization with custom functions。示例,具有以下功能:

def custom(text):
    return text[0]

【问题讨论】:

  • 您可以使用 np.vectorize numpy.org/doc/stable/reference/generated/numpy.vectorize.html 对任何函数进行矢量化。然而,根据 numpy 本身,它的主要语法糖及其实现是一个 for 循环。我不确定您要达到什么目的,但使用内置函数通常是很好的做法。
  • 即使np.char 函数也使用python 字符串方法,并且并不比使用相同方法的列表推导更快。字符串无法像使用数字 dtypes 那样进行快速“矢量化”。

标签: pandas numpy vectorization numpy-ndarray array-broadcasting


【解决方案1】:

numpy 没有实现快速字符串方法(就像它对数字 dtypes 所做的那样)。所以np.char 代码更多是为了方便而不是性能。

In [124]: alist=["sample1-sample","sample2-sample"]
In [125]: arr = np.array(alist)
In [126]: carr = np.char.array(alist)

简单的列表理解与您的代码:

In [127]: [item.split('-')[0] for item in alist]
Out[127]: ['sample1', 'sample2']
In [128]: np.char.array(carr.split('-'))[:,0]
Out[128]: chararray([b'sample1', b'sample2'], dtype='|S7')
In [129]: timeit [item.split('-')[0] for item in alist]
664 ns ± 32.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [130]: timeit np.char.array(carr.split('-'))[:,0]
20.5 µs ± 297 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

对于剪切字符串的简单任务,有一种快速的numpy 方式——使用更短的dtype

In [131]: [item[0] for item in alist]
Out[131]: ['s', 's']
In [132]: carr.astype('S1')
Out[132]: chararray([b's', b's'], dtype='|S1')

但假设这只是一个示例,而不是您现实世界的自定义操作,我建议使用列表。

np.char 建议使用np.char 函数和普通数组,而不是np.char.array。功能基本相同。但是使用上面的arr

In [140]: timeit np.array(np.char.split(arr, '-').tolist())[:,0]
13.8 µs ± 90.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

np.char 函数通常会生成字符串 dtype 数组,但 split 会创建一个对象 dtype 列表数组:

In [141]: np.char.split(arr, '-')
Out[141]: 
array([list(['sample1', 'sample']), list(['sample2', 'sample'])],
      dtype=object)

Object dtype 数组本质上是列表。

In [145]: timeit [item[0] for item in np.char.split(arr, '-').tolist()]
9.08 µs ± 27.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

您的代码相对较慢,因为将这个列表数组转换为新的chararray 需要时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    • 2020-05-29
    • 2019-11-09
    相关资源
    最近更新 更多