Python 将字符串数组与二维数组匹配
我有一个字符串数组(Python 将字符串数组与二维数组匹配,python,arrays,python-2.7,numpy,Python,Arrays,Python 2.7,Numpy,我有一个字符串数组(gene\u name\u list)。我需要在另一个2D数组(fully_split)中查找第一个数组的每个字符串所在的行。当然,我可以像这样用蛮力解决它: longest_gene_name = len(max(gene_name_list, key=len)) ensembl_list = np.full((len(gene_name_list)), '', dtype='U{}'.format(longest_gene_name)) for idx, gene_nam
gene\u name\u list
)。我需要在另一个2D
数组(fully_split
)中查找第一个数组的每个字符串所在的行。当然,我可以像这样用蛮力解决它:
longest_gene_name = len(max(gene_name_list, key=len))
ensembl_list = np.full((len(gene_name_list)), '', dtype='U{}'.format(longest_gene_name))
for idx, gene_name in enumerate(gene_name_list):
for row in fully_split:
if gene_name in row:
ensembl_list[idx] = row[0]
但是时间太长了,我需要一个更快的解决方案
行[0]
包含我要映射到的特殊符号。因此,如果找到一个字符串,它将在行[1:://code>部分中找到,然后我取行[0]
。不相关,但要澄清。除了执行时间之外,我认为您发布的暴力方法与您用文字描述的不一致:
我需要在另一个2D数组中查找行,其中第一个数组的每个字符串都存在
您的代码最多只能找到那里的所有行二维数组的行中至少有一个一维数组的字符串
下面的代码使用正则表达式执行您在Word中提出的要求
import re
pattern = r'*'.join(map(re.escape, np.sort(gene_name_list)))
rows = [''.join(np.sort(x)) for x in fully_split]
res = [re.search(pattern, r) for r in rows]
由于顺序不相关,gene\u name\u列表
按字典顺序排序,字符串使用regex特殊字符'*'
作为定界符连接。这是将要搜索的模式。
然后,2D数组的每一行都被完全分割
再次按字典顺序排序,并将字符串连接起来形成一个字符串。对每行执行正则表达式搜索,以检查是否存在匹配项
res
是一个列表,对于未找到匹配项的行,您将获得None
,并且相应的MatchObject
是一个匹配项
这说明了这一概念。为了更接近预期结果(存储行的第一个元素),请将最后一行替换为:
res = [l[0] if re.search(pattern, r) else None for r, l in zip(rows, fully_split)]
除了执行时间,我不认为您发布的暴力方法与您用文字描述的一致:
我需要在另一个2D数组中查找行,其中第一个数组的每个字符串都存在
您的代码最多只能找到那里的所有行二维数组的行中至少有一个一维数组的字符串
下面的代码使用正则表达式执行您在Word中提出的要求
import re
pattern = r'*'.join(map(re.escape, np.sort(gene_name_list)))
rows = [''.join(np.sort(x)) for x in fully_split]
res = [re.search(pattern, r) for r in rows]
由于顺序不相关,gene\u name\u列表
按字典顺序排序,字符串使用regex特殊字符'*'
作为定界符连接。这是将要搜索的模式。
然后,2D数组的每一行都被完全分割
再次按字典顺序排序,并将字符串连接起来形成一个字符串。对每行执行正则表达式搜索,以检查是否存在匹配项
res
是一个列表,对于未找到匹配项的行,您将获得None
,并且相应的MatchObject
是一个匹配项
这说明了这一概念。为了更接近预期结果(存储行的第一个元素),请将最后一行替换为:
res = [l[0] if re.search(pattern, r) else None for r, l in zip(rows, fully_split)]
根据你的描述,我做了几个假设:
-二维数组是矩形的(即不是dtype=object
),否则NumPy性能将毫无用处。
-len(完全分割)==len(基因名称列表)
,因为您的代码示例具有ensembl\u列表[idx]=行[0]
,idx
是从gene\u名称列表
>>> gene_name_list = np.array('a bb c d eee'.split())
>>> fully_split = np.array([
... 'id1 a bb c d eee'.split(), # yes
... 'id2 f g hh iii j'.split(),
... 'id3 kk ll a nn o'.split(), # yes
... 'id4 q rr c t eee'.split(), # yes
... 'id5 v www xx y z'.split()
... ])
>>> longest_gene_name = len(max(gene_name_list, key=len))
>>> dtype = 'U{}'.format(longest_gene_name)
>>> ensembl_list = np.zeros_like(gene_name_list, dtype=dtype)
>>> mask = np.isin(fully_split, gene_name_list).any(axis=1)
>>> ensembl_list[mask] = fully_split[mask, 0]
>>> ensembl_list
array(['id1', '', 'id3', 'id4', ''], dtype='<U3')
>>gene\u name\u list=np.array('a bb c d eee'.split())
>>>完全分割=np.array([
…id1 a bb c d eee.split(),#是
…id2 f g hh iii j'.split(),
…id3 kk ll a nn o.split(),#是
…id4 q rr c t eee'.split(),#是
…id5 v www xx y z.split()
... ])
>>>最长的基因名称=len(最大值(基因名称列表,键=len))
>>>数据类型='U{}'。格式(最长的基因名称)
>>>ensembl_list=np.zero_like(基因名列表,dtype=dtype)
>>>掩码=np.isin(完全分割,基因名称列表)。任意(轴=1)
>>>ensembl_列表[掩码]=完全拆分[掩码,0]
>>>ensembl_列表
数组(['id1','','id3','id4',''),dtype='根据您的描述,我做了几个假设:
-二维数组是矩形的(即不是dtype=object
),否则NumPy性能将毫无用处。
-len(完全分割)==len(基因名称列表)
,因为您的代码示例具有ensembl\u列表[idx]=行[0]
,idx
是从gene\u名称列表
>>> gene_name_list = np.array('a bb c d eee'.split())
>>> fully_split = np.array([
... 'id1 a bb c d eee'.split(), # yes
... 'id2 f g hh iii j'.split(),
... 'id3 kk ll a nn o'.split(), # yes
... 'id4 q rr c t eee'.split(), # yes
... 'id5 v www xx y z'.split()
... ])
>>> longest_gene_name = len(max(gene_name_list, key=len))
>>> dtype = 'U{}'.format(longest_gene_name)
>>> ensembl_list = np.zeros_like(gene_name_list, dtype=dtype)
>>> mask = np.isin(fully_split, gene_name_list).any(axis=1)
>>> ensembl_list[mask] = fully_split[mask, 0]
>>> ensembl_list
array(['id1', '', 'id3', 'id4', ''], dtype='<U3')
>>gene\u name\u list=np.array('a bb c d eee'.split())
>>>完全分割=np.array([
…id1 a bb c d eee.split(),#是
…id2 f g hh iii j'.split(),
…id3 kk ll a nn o.split(),#是
…id4 q rr c t eee'.split(),#是
…id5 v www xx y z.split()
... ])
>>>最长的基因名称=len(最大值(基因名称列表,键=len))
>>>数据类型='U{}'。格式(最长的基因名称)
>>>ensembl_list=np.zero_like(基因名列表,dtype=dtype)
>>>掩码=np.isin(完全分割,基因名称列表)。任意(轴=1)
>>>ensembl_列表[掩码]=完全拆分[掩码,0]
>>>ensembl_列表
数组(['id1','','id3','id4',''),dtype='是的,这就是答案。唯一的问题是,np.isin
在早期的numpy
版本中不存在,我正在使用python2.7
。以某种方式用in1d
重写它是有意义的……看看fornp.isin
它实际上是一个单行程序来实现的(假设1.8.0中引入的invert参数可用于python 2.7)是的,这就是答案。唯一的问题是,np.isin
在早期的numpy
版本中不存在,我正在使用python2.7
。以某种方式用in1d
重写它是有意义的……看看fornp.isin
它实际上是一个单行程序来实现的(假设1.8.0中引入的invert参数可用于python 2.7)。