Python:确定存储在数据框中的三个文本字符串是否有任何共同的单词

时间:2018-05-09 12:56:27

标签: python string pandas text split

说我有以下数据框df

      A             B               C
0     mom;dad;son;  sister;son;     yes;no;maybe;
1     dad;          daughter;niece; no;snow;
2     son;dad;      cat;son;dad;    tree;dad;son;
3     daughter;mom; niece;          referee;
4     dad;daughter; cat;            dad;

您想要检查列ABC之间是否存在常用词,并使用{{1创建列D如果有和1,如果没有。要使一个词很常见,它就足以让它出现在三列中的两列中。

结果应该是:

0

我试图通过这样做来实现:

      A             B               C              D
0     mom;dad;son;  sister;son;     yes;no;maybe;  1
1     dad;          daughter;niece; no;snow;       0
2     son;dad;      cat;son;dad;    tree;dad;son;  1
3     daughter;mom; niece;          referee;       0
4     dad;daughter; cat;            dad;           1

但是,生成的for index, row in df.iterrows(): w1=row['A'].split(';') w2=row['B'].split(';') w3=row['C'].split(';') if len(set(w1).intersection(w2))>0 or len(set(w1).intersection(w3))>0 or len(set(w2).intersection(w3))>0: df['D'][index]==1 else: df['D'][index]==0 列仅承载D,因为(可能)我没有将w1中的每个单词与w2和w3中的其他单词进行比较。我怎么能做到这一点?

4 个答案:

答案 0 :(得分:8)

使用stack + pandas.Series.str.get_dummies

df.assign(
    D=df.stack().str.get_dummies(';').sum(level=0).gt(1).any(1).astype(int)
)

               A                B              C  D
0   mom;dad;son;      sister;son;  yes;no;maybe;  1
1           dad;  daughter;niece;       no;snow;  0
2       son;dad;     cat;son;dad;  tree;dad;son;  1
3  daughter;mom;           niece;       referee;  0
4  dad;daughter;             cat;           dad;  1

详细

请注意,当我们堆叠并获取虚拟对象时,中间结果如下所示:

     cat  dad  daughter  maybe  mom  niece  no  referee  sister  snow  son  tree  yes
0 A    0    1         0      0    1      0   0        0       0     0    1     0    0
  B    0    0         0      0    0      0   0        0       1     0    1     0    0
  C    0    0         0      1    0      0   1        0       0     0    0     0    1
1 A    0    1         0      0    0      0   0        0       0     0    0     0    0
  B    0    0         1      0    0      1   0        0       0     0    0     0    0
  C    0    0         0      0    0      0   1        0       0     1    0     0    0
2 A    0    1         0      0    0      0   0        0       0     0    1     0    0
  B    1    1         0      0    0      0   0        0       0     0    1     0    0
  C    0    1         0      0    0      0   0        0       0     0    1     1    0
3 A    0    0         1      0    1      0   0        0       0     0    0     0    0
  B    0    0         0      0    0      1   0        0       0     0    0     0    0
  C    0    0         0      0    0      0   0        1       0     0    0     0    0
4 A    0    1         1      0    0      0   0        0       0     0    0     0    0
  B    1    0         0      0    0      0   0        0       0     0    0     0    0
  C    0    1         0      0    0      0   0        0       0     0    0     0    0

前一列嵌入索引的第二级。因此,我想总结第一级,以便查看该单词出现的次数。

那个临时总结看起来像:

   cat  dad  daughter  maybe  mom  niece  no  referee  sister  snow  son  tree  yes
0    0    1         0      1    1      0   1        0       1     0    2     0    1
1    0    1         1      0    0      1   1        0       0     1    0     0    0
2    1    3         0      0    0      0   0        0       0     0    3     1    0
3    0    0         1      0    1      1   0        1       0     0    0     0    0
4    1    2         1      0    0      0   0        0       0     0    0     0    0

请注意,我们会在第1行,'son'和第3行'dad'中抓取'son',依此类推。

如果它出现在多个列中(因此gt(1)),那么我想将其计为1(因此any(1).astype(int))。

答案 1 :(得分:4)

使用collections.Counter

,此单行创建您需要的内容
from collections import Counter

df['D'] = df.applymap(lambda x: [i for i in x.split(';') if i]).apply(lambda x: int(Counter(x.A+x.B+x.C).most_common(1)[0][1]!=1), axis=1)

答案 2 :(得分:3)

您可以通过修改拼写错误来使用您的代码:将setBounds(new Rectangle(x,y,width,height))替换为==

答案 3 :(得分:1)

试试这个:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4 4" id="curve-text" width="200" height="200">
</svg>

def find_common(row): A_list=set(row['A'].rsplit(';')[:-1]) B_list=set(row['B'].rsplit(';')[:-1]) C_list=set(row['C'].rsplit(';')[:-1]) if ((len(A_list.intersection(B_list))) or (len(B_list.intersection(C_list))) or (len(A_list.intersection(C_list)))): return 1 else: return 0