如何找到数组中的哪些字符串是python中另一个字符串的子字符串?

时间:2019-07-11 18:06:18

标签: python arrays numpy

我有一个numpy的字符串数组(str8192),其中第二列是事物的名称。为此,可以说此数组称为thingList。我有两个字符串,string1和string2。我正在尝试获取事物列表第二列中字符串1或字符串2中每个项目的列表。目前,我正在使用for循环运行此函数,但我希望有一种更快的方法,我不知道关于,我是编程新手。

找到匹配项后,我也想记录第一列中与匹配项相同的行。

任何帮助您加快速度的方法都将受到赞赏,因为thingList非常大,并且此函数在各种数组中都可以运行很多。

tempThing = []
tempCode = []

for i in range(thingList.shape[0]):
        if thingList[i][1].lower() in string1.lower() or thingList[i] [1].lower() in string2.lower():
            tempThing.append(thingList[i][1])
            tempCode.append(thingList[i][0])

此代码可以正常工作,但绝对是我程序中的瓶颈,并且减慢了速度。

2 个答案:

答案 0 :(得分:0)

您可以使用列表推导,它们比传统的for循环要快。此外,您可以做一些小的改进以使代码运行更快:

thing_list = [['Thing1', 'bo'], ['Thing2', 'b'], [ 'Thing3', 'ca'],
              ['Thing4', 'patrick']]*100
string1 = 'bobby'
string2 = 'patrick neils'

# Compute your lower strings before the for loops to avoid
# calling the function at each loop
st1_lower = string1.lower()
st2_lower = string2.lower()

# You can store both the item and the name in the same array to reduce
# the computing time and do it in one list comprehension
result = [[x[0], x[1]] for x in thing_list
          if (x[1].lower() in st1_lower) or (x[1].lower() in st2_lower) ]

输出:

[['Thing1', 'bo'], ['Thing2', 'b'], ['Thing4', 'patrick']]
  

性能:

     

对于循环:每个循环172 µs±9.59 µs(平均±标准偏差,共运行7次,每个循环10000个)

     

列表理解:每个循环81.1 µs±2.17 µs(平均±标准偏差,共运行7次,每个循环10000次)

答案 1 :(得分:0)

Numpy数组将默认在行上进行迭代,因此无需执行for i in range(...)

x = np.array(list(range(3)), list(range(3,6)))

for i in x:
    print(i)

[0 1 2]
[3 4 5]

# This yields the same result, so use the former
for i in range(x.shape[0]):
    print(x[i])

[0 1 2]
[3 4 5]

接下来,您要花费大量时间反复进行str.lower()。我可能会提前放下所有琴弦:

y = np.array([list('ABC'), list('DEF')])

np.char.lower(y)
array([['a', 'b', 'c'],
       ['d', 'e', 'f']],
      dtype='<U1')

# apply this to string1 and string2
l_str1, l_str2 = string1.lower(), string2.lower()

现在,您的循环应如下所示:

l_str1, l_str2 = string1.lower(), string2.lower()

for val1, val2 in thingList:
    to_check = val2.lower()

    if to_check in l_str1 or to_check in l_str2:
        tempThing.append(val1)
        tempCode.append(val2)

现在您可以将其应用于列表理解:

# you can zip these together so you aren't using str.lower() 
# for all of your if statements
tmp = ((*uprow) for uprow, (a, b) in zip(thingList, np.char.lower(thingList))
       if b in l_str1 or b in l_str2)

# this will unpack pairs
tempThing, tempCode = zip(*tmp)