首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在numpy数组中搜索模式

在numpy数组中搜索模式
EN

Stack Overflow用户
提问于 2017-01-05 18:27:07
回答 5查看 9.5K关注 0票数 6

是否有一种简单的方法可以根据某种模式在NumPy数组中找到所有相关元素?

例如,考虑以下数组:

代码语言:javascript
复制
a = array(['zzzz', 'zzzd', 'zzdd', 'zddd', 'dddn', 'ddnz', 'dnzn', 'nznz',
       'znzn', 'nznd', 'zndd', 'nddd', 'ddnn', 'dnnn', 'nnnz', 'nnzn',
       'nznn', 'znnn', 'nnnn', 'nnnd', 'nndd', 'dddz', 'ddzn', 'dznn',
       'znnz', 'nnzz', 'nzzz', 'zzzn', 'zznn', 'dddd', 'dnnd'], dtype=object)

我需要找到所有包含'**dd‘的组合。

我基本上需要一个函数,它接收数组作为输入,并返回一个包含所有相关元素的较小数组:

代码语言:javascript
复制
>> b = func(a, pattern='**dd')
>> b = array(['zzdd', 'zddd', 'zndd', 'nddd', 'nndd', 'dddd'], dtype=object)
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2017-01-05 19:04:25

因为事实证明你实际上是在和熊猫一起工作,所以有更简单的方法可以在系列赛级别上完成,而不是仅仅使用向量化字符串操作

代码语言:javascript
复制
In [32]: s = pd.Series(['zzzz', 'zzzd', 'zzdd', 'zddd', 'dddn', 'ddnz', 'dnzn', 'nznz',
    ...:        'znzn', 'nznd', 'zndd', 'nddd', 'ddnn', 'dnnn', 'nnnz', 'nnzn',
    ...:        'nznn', 'znnn', 'nnnn', 'nnnd', 'nndd', 'dddz', 'ddzn', 'dznn',
    ...:        'znnz', 'nnzz', 'nzzz', 'zzzn', 'zznn', 'dddd', 'dnnd'])

In [33]: s[s.str.endswith("dd")]
Out[33]: 
2     zzdd
3     zddd
10    zndd
11    nddd
20    nndd
29    dddd
dtype: object

它产生了一个系列,或者如果你真的坚持的话:

代码语言:javascript
复制
In [34]: s[s.str.endswith("dd")].values
Out[34]: array(['zzdd', 'zddd', 'zndd', 'nddd', 'nndd', 'dddd'], dtype=object)

如果您愿意,也可以使用正则表达式:

代码语言:javascript
复制
In [49]: s[s.str.match(".*dd$")]
Out[49]: 
2     zzdd
3     zddd
10    zndd
11    nddd
20    nndd
29    dddd
dtype: object
票数 9
EN

Stack Overflow用户

发布于 2017-01-05 18:51:10

下面是一种使用numpy.core.defchararray.rfind获取匹配的最后一个索引的方法,然后我们检查该索引是否为2减去每个字符串的长度。现在,每个字符串的长度在这里是4,所以我们将查找最后一个索引,即4 - 2 = 2

因此,实施如下:

代码语言:javascript
复制
a[np.core.defchararray.rfind(a.astype(str),'dd')==2]

如果字符串长度不相等,我们需要得到长度,减去2,然后比较-

代码语言:javascript
复制
len_sub = np.array(list(map(len,a)))-len('dd')
a[np.core.defchararray.rfind(a.astype(str),'dd')==len_sub]

为了测试这一点,让我们在给定示例的末尾添加一个以dd结尾的更长的字符串-

代码语言:javascript
复制
In [121]: a = np.append(a,'ewqjejwqjedd')

In [122]: len_sub = np.array(list(map(len,a)))-len('dd')

In [123]: a[np.core.defchararray.rfind(a.astype(str),'dd')==len_sub]
Out[123]: array(['zzdd', 'zddd', 'zndd', 'nddd', 'nndd', 'dddd',\
                 'ewqjejwqjedd'], dtype=object)
票数 4
EN

Stack Overflow用户

发布于 2017-01-05 18:43:13

我不是numpy专家。但是,我理解您希望创建一个过滤的numpy数组,而不是标准的python数组,从python数组转换到numpy数组需要时间和内存,这是非常糟糕的选择。

不确定您指的是regex,而是通配符,在这种情况下,正确的选择是带有fnmatch模式的??dd模块(最后是任何2个字符+ dd )。

(替代解决方案将涉及re.match()..dd$作为一种模式)。

我将计算符合标准的索引,然后使用take提取子列表:

代码语言:javascript
复制
from numpy import array
import fnmatch

a = array(['zzzz', 'zzzd', 'zzdd', 'zddd', 'dddn', 'ddnz', 'dnzn', 'nznz',
       'znzn', 'nznd', 'zndd', 'nddd', 'ddnn', 'dnnn', 'nnnz', 'nnzn',
       'nznn', 'znnn', 'nnnn', 'nnnd', 'nndd', 'dddz', 'ddzn', 'dznn',
       'znnz', 'nnzz', 'nzzz', 'zzzn', 'zznn', 'dddd', 'dnnd'], dtype=object)

def func(ar,pattern):
    indices = [i for i,x in enumerate(ar) if fnmatch.fnmatch(x,pattern)]
    return ar.take(indices)

print(func(a,"??dd"))

结果:

代码语言:javascript
复制
['zzdd' 'zddd' 'zndd' 'nddd' 'nndd' 'dddd']

regex版本(当然也会有相同的结果):

代码语言:javascript
复制
from numpy import array
import re

def func(ar,pattern):
    indices = [i for i,x in enumerate(ar) if re.match(pattern,x)]
    return ar.take(indices)

print(func(a,"..dd$"))
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41492117

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档