我想从每行的另一个数据帧中减去或删除一个数据框中的单词。
这是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命名:df1
和df2
。你会这样做:
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
我已经为这些数据帧(sentence
和delete_word
(中的某些数据点分配了变量,但这只是为了理解。不这样做,您可以很容易地将这些代码压缩为几行更短的代码。