在numpy数组中查找包含子字符串的条目?

SiO*_*iOx 7 numpy where string-comparison python-3.4

我试图在包含带有np.where和条件的子字符串的数组中查找条目:

import numpy as np
foo = "aa"
bar = np.array(["aaa", "aab", "aca"])
np.where(foo in bar)
Run Code Online (Sandbox Code Playgroud)

这只返回一个空数组.
为什么会这样?
还有一个很好的替代解决方案吗?

Div*_*kar 12

我们可以用来在每个元素中np.core.defchararray.find找到foo字符串的位置,如果找不到bar则会返回-1.因此,它可以用于foo通过检查-1输出来检测每个元素中是否存在find.最后,我们将np.flatnonzero用来获得匹配的索引.所以,我们会有一个实现,就像这样 -

np.flatnonzero(np.core.defchararray.find(bar,foo)!=-1)
Run Code Online (Sandbox Code Playgroud)

样品运行 -

In [91]: bar
Out[91]: 
array(['aaa', 'aab', 'aca'], 
      dtype='|S3')

In [92]: foo
Out[92]: 'aa'

In [93]: np.flatnonzero(np.core.defchararray.find(bar,foo)!=-1)
Out[93]: array([0, 1])

In [94]: bar[2] = 'jaa'

In [95]: np.flatnonzero(np.core.defchararray.find(bar,foo)!=-1)
Out[95]: array([0, 1, 2])
Run Code Online (Sandbox Code Playgroud)

  • `np.char.find` 是这个函数的简写。 (5认同)

hpa*_*ulj 6

看一些使用的例子in

In [19]: bar = np.array(["aaa", "aab", "aca"])

In [20]: 'aa' in bar
Out[20]: False

In [21]: 'aaa' in bar
Out[21]: True

In [22]: 'aab' in bar
Out[22]: True

In [23]: 'aab' in list(bar) 
Run Code Online (Sandbox Code Playgroud)

看起来in与数组一起使用时就像数组是一个列表一样。 ndarray确实有一个__contains__方法,所以in有效,但可能很简单。

但无论如何,请注意,它in alist不会检查子字符串。执行子strings __contains__字符串测试,但我不知道有任何内置类可以将测试传播到组件字符串。

如图Divakar所示,有一组 numpy 函数将字符串方法应用于数组的各个元素。

In [42]: np.char.find(bar, 'aa')
Out[42]: array([ 0,  0, -1])
Run Code Online (Sandbox Code Playgroud)

Docstring:
该模块包含一组用于向量化字符串操作的函数和方法。的首选别名defchararraynumpy.char.

对于这样的操作,我认为np.char速度与以下内容大致相同:

In [49]: np.frompyfunc(lambda x: x.find('aa'), 1, 1)(bar)
Out[49]: array([0, 0, -1], dtype=object)

In [50]: np.frompyfunc(lambda x: 'aa' in x, 1, 1)(bar)
Out[50]: array([True, True, False], dtype=object)
Run Code Online (Sandbox Code Playgroud)

进一步的测试表明,该ndarray __contains__操作对flat数组的版本进行操作 - 也就是说,形状不会影响其行为。