从另一个数据帧的列中的另一个单词列表中删除数据帧的一列中每行中的单词



我想从每行的另一个数据帧中减去或删除一个数据框中的单词。

这是pyspark数据帧的主表/列。

+----------+--------------------+
|  event_dt|           cust_text|
+----------+--------------------+
|2020-09-02|hi fine i want to go|
|2020-09-02|i need  a line hold |
|2020-09-02|i have the  60 packs|
|2020-09-02|hello want you teach|

下面是另一个pyspark数据帧。该数据帧中的单词需要从上述cust_text列的主表中删除,无论单词出现在每行中的哪个位置。例如,"want"将从第一个数据帧中出现的每一行中删除。

+-------+
|column1|
+-------+
|   want|
|because|
|   need|
|  hello|
|      a|
|   have|
|     go|
+-------+

这可以在pyspark或panda中完成。我曾尝试使用Python、Pyspark、pandas在谷歌上搜索该解决方案,但仍然无法基于单列表从主表中删除单词。

结果应该是这样的:

+----------+--------------------+
|  event_dt|           cust_text|
+----------+--------------------+
|2020-09-02|hi fine i to        |
|2020-09-02|i line hold         |
|2020-09-02|i the 60 packs      |
|2020-09-02|you teach           |
+----------+--------------------+

如果你只想删除df2对应行中的单词,你可以按如下方式删除,但对于大型数据集来说可能会很慢,因为它只能部分使用快速C实现:

# define your helper function to remove the string
def remove_string(ser_row):
return ser_row['cust_text'].replace(ser_row['remove'], '')
# create a temporary column with the string to remove in the first dataframe
df1['remove']= df2['column1']
df1= df1.apply(remove_string, axis='columns')
# drop the temporary column afterwards
df1.drop(columns=['remove'], inplace=True)

结果看起来像:

Out[145]: 
0        hi fine i  to go
1    i need   lines hold 
2    i have the  60 packs
3           can you teach
dtype: object

但是,如果您想从列中删除df2列中的所有单词,则需要采取不同的操作。不幸的是,str.replace在这里对常规字符串没有帮助,除非您想为第二个数据帧中的每一行调用它。因此,如果第二个数据帧不是太大,可以创建一个正则表达式来使用str.replace

import re
replace=re.compile(r'b(' + ('|'.join(df2['column1'])) + r')b')
df1['cust_text'].str.replace(replace, '')

输出为:

Out[184]: 
0      hi fine i  to 
1    i    lines hold 
2    i  the  60 packs
3       can you teach
Name: cust_text, dtype: object

如果你不喜欢保留的重复空格,你可以执行以下操作:

df1['cust_text'].str.replace(replace, '').str.replace(re.compile('s{2,}'), ' ')

补充:如果不仅没有单词的文本是相关的,而且单词本身也是相关的。我们怎样才能得到被替换的单词。这里有一个尝试,如果可以识别一个字符,它将不会出现在文本中,则会起作用。假设这个字符是@,那么您可以(在不替换的原始列值上(:

# enclose each keywords in @
ser_matched= df1['cust_text'].replace({replace: r'@1@'}, regex=True)
# now remove the rest of the line, which is unmatched
# this is the part of the string after the last occurance
# of a @
ser_matched= ser_matched.replace({r'^(.*)@.*$': r'1', '^@': ''}, regex=True)
# and if you like your keywords to be in a list, rather than a string
# you can split the string at last
ser_matched.str.split(r'@+')

此解决方案将针对熊猫。如果我正确理解您的挑战,那么您希望从第二个DataFrame的column1中出现的列cust_text中删除所有单词。让我们为相应的DataFrames命名:df1df2。你会这样做:

for i in range(len(df1)):
sentence = df1.loc[i, "cust_text"]
for j in range(len(df2)):
delete_word = df2.loc[j, "column1"]
if delete_word in sentence:
sentence = sentence.replace(delete_word, "")
df1.loc[i, "cust_text"] = sentence

我已经为这些数据帧(sentencedelete_word(中的某些数据点分配了变量,但这只是为了理解。不这样做,您可以很容易地将这些代码压缩为几行更短的代码。

最新更新