在文本文件中搜索字符串的位置

时间:2018-11-29 12:31:32

标签: python arrays pandas numpy

我有一个文本文件(file1),其中行包含字符串条目。每行的第一个元素对应一个标签,而每行的所有后续条目均包含字符串。相同的字符串可能会出现在多行中的不同位置。 file1中的不同行具有不同的列数。

将此作为file1的示例(您可以从here下载file1

label1: aa  bb  dd  zz  yy  ww
label2: pp  qq  aa  ss
label3: mm  aa  gg  qq  rr  kk
label4: uu  ss  ll  pp
label5: hh  jj  qq  ss  uu

独立于file1,我有一个一维Numpy数组arr),其中包含字符串唯一条目)。 arr中的每个字符串都在file1的一个或多个行(在file1中的条目,但第一列除外)中被提及。考虑以下内容作为arr的示例。

arr = np.array(['aa', 'qq', 'ss', 'zz', 'ss', 'pp', 'dd'])

使用python ,我想将arrfile1进行比较,并arr中找到字符串的索引 相似。以下示例说明了如何确定相似性:如果arr的{​​{1}}的entry1,entry4和entry5在file1的同一行中具有特征,那么我想获取具有这些索引的元组(或列表)条目(1,4,5)。我想对所有这样的小组这样做。

在上面给出的arrfile1的示例中,我们看到('aa', 'dd', 'zz')存在于file1的第一行中(因此,我希望有元组{ {1}})与此类似,(0,3,6)的第四行中的('ss', 'pp')具有arr功能,所以我也想拥有元组file1。最后,(4,5)('qq', 'ss')的第五行中将导致元组file1

目前,当我尝试使用(1,2)来阅读file1.txt时遇到错误

np.genfromtxt('file1.txt')

如何正确阅读ValueError: Some errors were detected ! Line #2 (got 5 columns instead of 7) Line #4 (got 5 columns instead of 7) Line #5 (got 6 columns instead of 7) 并达到所需的结果?我将不胜感激。

2 个答案:

答案 0 :(得分:0)

np.genfromtxt的输出是一个数组,因此每行中的列数不同的事实意味着您必须适当地处理缺失值。您可能会考虑仅使用csv遍历文件,但另一种选择是像这样使用pd.read_csv

> pd.read_csv('file1.txt', sep=r'\s+', header=None, dtype='|U').values[:,1:]
> array([['aa', 'bb', 'dd', 'zz', 'yy', 'ww'],
         ['pp', 'qq', 'aa', 'ss', nan, nan],
         ['mm', 'aa', 'zz', 'qq', 'rr', 'dd'],
         ['uu', 'ss', 'll', 'pp', nan, nan],
         ['hh', 'jj', 'qq', 'ss', 'uu', nan]], dtype=object)

如果性能很重要,并且字符串确实是所有两个字符,则可以在构造函数中设置dtype='|S2'。根据您使用的pandas的版本,您可能还需要设置engine='python'以避免收到有关正则表达式的警告(但不要这样做,除非您遇到麻烦,否则它会变慢并且可能不必要)。

您的arr在2和4处有一个重复的元素,但是假设没错,整个过程看起来像这样:

In [1] a=pd.read_csv('file1.txt', sep=r'\s+', header=None).values[:,1:].astype('<U2')
In [2] arr = np.array(['aa', 'qq', 'ss', 'zz', 'ss', 'pp', 'dd'])
In [3] [tuple(j for j, el in enumerate(arr) if el in set(a[i])) for i in range(len(a))]
Out[4] [(0, 3, 6), (0, 1, 2, 4, 5), (0, 1, 3, 6), (2, 4, 5), (1, 2, 4)]

答案 1 :(得分:0)

就有人要求在Python上解决它,而没有提及熊猫:

  

使用 python ,我想将arr与file1进行比较,然后...

我可以建议简单易用的算法:

arr = ['aa', 'qq', 'ss', 'zz', 'ss', 'pp', 'dd']
with open('file.csv') as inp:
    for line in inp.readlines(): # scan csv line by line
        words = line.strip().split(' ') # split line to words
        label = words[0]   # get label
        items = words[1:]  # get all but label
        lst = []           # result tuple/list for this line
        for i in range(len(arr)):   
            if arr[i] in items and arr.index(arr[i]) == i:
                lst.append(i)
        print ('{}: {}'.format(label, lst))

注意,arr.index(arr[i]) == i检查数组中的项是否重复