是否有一种简单的方法可以根据某种模式在NumPy数组中找到所有相关元素?
例如,考虑以下数组:
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‘的组合。
我基本上需要一个函数,它接收数组作为输入,并返回一个包含所有相关元素的较小数组:
>> b = func(a, pattern='**dd')
>> b = array(['zzdd', 'zddd', 'zndd', 'nddd', 'nndd', 'dddd'], dtype=object)发布于 2017-01-05 19:04:25
因为事实证明你实际上是在和熊猫一起工作,所以有更简单的方法可以在系列赛级别上完成,而不是仅仅使用向量化字符串操作
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它产生了一个系列,或者如果你真的坚持的话:
In [34]: s[s.str.endswith("dd")].values
Out[34]: array(['zzdd', 'zddd', 'zndd', 'nddd', 'nndd', 'dddd'], dtype=object)如果您愿意,也可以使用正则表达式:
In [49]: s[s.str.match(".*dd$")]
Out[49]:
2 zzdd
3 zddd
10 zndd
11 nddd
20 nndd
29 dddd
dtype: object发布于 2017-01-05 18:51:10
下面是一种使用numpy.core.defchararray.rfind获取匹配的最后一个索引的方法,然后我们检查该索引是否为2减去每个字符串的长度。现在,每个字符串的长度在这里是4,所以我们将查找最后一个索引,即4 - 2 = 2。
因此,实施如下:
a[np.core.defchararray.rfind(a.astype(str),'dd')==2]如果字符串长度不相等,我们需要得到长度,减去2,然后比较-
len_sub = np.array(list(map(len,a)))-len('dd')
a[np.core.defchararray.rfind(a.astype(str),'dd')==len_sub]为了测试这一点,让我们在给定示例的末尾添加一个以dd结尾的更长的字符串-
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)发布于 2017-01-05 18:43:13
我不是numpy专家。但是,我理解您希望创建一个过滤的numpy数组,而不是标准的python数组,从python数组转换到numpy数组需要时间和内存,这是非常糟糕的选择。
不确定您指的是regex,而是通配符,在这种情况下,正确的选择是带有fnmatch模式的??dd模块(最后是任何2个字符+ dd )。
(替代解决方案将涉及re.match()和..dd$作为一种模式)。
我将计算符合标准的索引,然后使用take提取子列表:
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"))结果:
['zzdd' 'zddd' 'zndd' 'nddd' 'nndd' 'dddd']regex版本(当然也会有相同的结果):
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$"))https://stackoverflow.com/questions/41492117
复制相似问题