基于文本匹配在 Pandas DataFrame 上加入和 运行 计算

Join and run calculations on Pandas DataFrame based on text matching

我有两个客户评论数据的数据框。

我的第一个数据框,'df' 包含 条原始客户评论,processed/cleaned 评论数据,以及情绪分数:

reviewBody                   reviewClean           sentimentScore
'I like these goggles'       'like goggles'        1
'I don't like these goggles' 'don't like goggles'  -1
'My strap broke'             'strap broke'         -1
 ...                         ...                  ...

我的第二个数据帧 'bigrams' 包含我第一个数据帧中称为 'reviewClean' 的字段中最常见的二元组:

topBigrams                 frequency
'like goggles'               150 
'strap broke'                100
  ...                        ...          

我的目标是拿走我的每一个 topBigrams,例如'like goggles' 或 'strap broke',查找包含每个二元组的每个 'reviewClean' 和整个评论的相关情绪,并计算每个 topBigram 的平均情绪分数。

我的最终结果看起来像这样(数字纯粹是为了说明):

topBigrams                 frequency   avgSentiment
'like goggles'             150         .98
'strap broke'              100         -.90
 ...                        ...         ...

根据这些数据,我会寻找每个二元组的趋势,以更简洁的方式确定正面或负面情绪的驱动因素。

我什至不知道从哪里开始。非常感谢您对此处潜在方法的任何见解。

您将不得不进行交叉连接 以检查每条评论是否包含所有二元语法。由于需要进行逐行字符串比较,因此无法使用 apply

df = pd.DataFrame([['I like these goggles', 'like goggles', 1],
        ["I don't like these goggles", "don't like goggles", -1],
        ['My strap broke', 'strap broke', -1]],
        columns=['reviewBody', 'reviewClean', 'sentimentScore'])

bigrams = pd.DataFrame([['like goggles', 150],
        ['strap broke', 100]],
        columns=['topBigrams', 'frequency'])

dfx = bigrams.assign(key=1).merge(df.assign(key=1), on='key').drop('key', 1)
dfx['has_bigram'] = dfx.apply(lambda x: x.get('topBigrams') in x.get('reviewClean'), axis=1)

在检查每个已清理评论中的二元组后,您可以使用 groupby 计算二元组的平均情绪,仅适用于二元组存在的地方。然后将其合并回 bigrams 数据框。

bigrams.merge(dfx.groupby(['topBigrams', 'has_bigram'])
                 .mean()
                 .reset_index()
                 .query('has_bigram')
                 .rename(columns={'sentimentScore':'avgSentiment'})
                 .get(['topBigrams', 'avgSentiment']),
              on='topBigrams')

# returns:
     topBigrams  frequency  avgSentiment
0  like goggles        150             0
1   strap broke        100            -1