如何在Pandas DataFrame的列的所有行中识别字符串重复?

时间:2018-12-03 22:22:15

标签: python pandas dataframe search pattern-matching

我正在尝试一种方法来最好地解决此问题。如果我有这样的数据框:

Module---|-Line Item---|---Formula-----------------------------------------|-repetition?|--What repeated--------------------------------|---Where repeated
Module 1-|Line Item 1--|---hello[SUM: hello2]------------------------------|----yes-----|--hello[SUM: hello2]---------------------------|---Module 1 Line item 2
Module 1-|Line Item 2--|---goodbye[LOOKUP: blue123] + hello[SUM: hello2]---|----yes-----|--hello[SUM: hello2], goodbye[LOOKUP: blue123]-|---Module 1 Line item 1, Module 2 Line Item 1
Module 2-|Line Item 1--|---goodbye[LOOKUP: blue123] + some other line item-|----yes-----|--goodbye[LOOKUP: blue123]---------------------|---Module 1 Line item 2

我该如何进行搜索以找到并确定中间或边缘或完整字符串上的重复?

抱歉,格式看起来不好 基本上,我已经填写了模块,订单项和公式列,但是我需要弄清楚某种搜索功能,可以将其应用于后三列中的每列。我不确定从哪里开始。

我想匹配出现在3个或更多单词之间的任何重复,例如,如果某个公式是1 + 2 + 3 + 4,并且在“公式”列中出现了4次,我想给布尔值以“是” “重复”列返回“在哪里重复”列上的1 + 2 + 3 + 4,并在最后一列返回出现的每个模块/行项目组合的列表。我确定一旦开始,我就可以对其进行进一步的调整。

1 个答案:

答案 0 :(得分:1)

这有点杂乱,无疑是执行某些步骤的更直接的方法,但是它对您的数据有效。

第1步:我只是将reset_index()(假设索引使用行号)将行号放入一列中。

df.reset_index(inplace=True)

然后我写了一个for循环,目的是检查每个给定值,如果该值在给定列中的任何位置(使用.str.contains()函数,如果是,则在哪里。然后将其存储信息在字典中。请注意,这里我使用+来拆分搜索的各种值,因为它们看起来像是数据集中的有效分隔符,但是您可以相应地进行调整

#the dictionary will have a key containing row number and the value we searched for
#the value will contain the module and line item values
result = {}
#create a rownumber variable so we know where in the dataset we are
rownumber = -1
#now we just iterate over every row of the Formula series
for row in df['Formula']:
    rownumber +=1
    #and also every relevant value within that cell
    for value in row.split('+'):
        #we clean the value from trailing/preceding whitespace
        value = value.strip()
        #and then we return our key and value and update our dictionary
        key = 'row:|:'+str(rownumber)+':|:'+value
        value = (df.loc[((df.Formula.str.contains(value,regex=False))) & (df.index!=rownumber),['Module','Line Item']])
        result.update({key:value})

我们现在可以将字典解包到我们有匹配项的列表中:

where_raw = []
what_raw = []
rows_raw = []
for key,value in zip(result.keys(),result.values()):
    if 'Empty' in str(value):
        continue
    else:
        where_raw.append(list(value['Module']+' '+value['Line Item']))
        what_raw.append(key.split(':|:')[2])
        rows_raw.append(int(key.split(':|:')[1]))

tempdf = pd.DataFrame({'row':rows_raw,'where':where_raw,'what':what_raw})

tempdf现在每次匹配包含一行,但是,我们希望在df中每原始行包含一行,因此我们将每个主行的所有匹配项合并为一个

where = []
what = []
rows = []        

for row in tempdf.row.unique():
    where.append(list(tempdf.loc[tempdf.row==row,'where']))
    what.append(list(tempdf.loc[tempdf.row==row,'what']))
    rows.append(row)
result = df.merge(pd.DataFrame({'index':rows,'where':where,'what':what}))

最后,我们现在可以通过将结果与原始数据帧合并来获得结果

result = df.merge(pd.DataFrame({'index':rows,'where':where,'what':what}),how='left',on='index').drop('index',axis=1)

最后,我们可以像这样添加repeated列: result['repeated'] = (result['what']!='')

 print(result)
 Module     Line Item   Formula                                         what                                                 where
 Module 1   Line Item 1 hello[SUM: hello2]                              ['hello[SUM: hello2]']                               [['Module 1 Line Item 2']]
 Module 1   Line Item 2 goodbye[LOOKUP: blue123] + hello[SUM: hello2]   ['goodbye[LOOKUP: blue123]', 'hello[SUM: hello2]']   [['Module 2 Line Item 1'], ['Module 1 Line Item 1']]
 Module 2   Line Item 1 goodbye[LOOKUP: blue123] + some other line item ['goodbye[LOOKUP: blue123]']                         [['Module 1 Line Item 2']]