【问题标题】:Calculating the sum of a column if it contains a string stored in another dataframe如果列包含存储在另一个数据框中的字符串,则计算列的总和
【发布时间】:2025-12-19 04:35:10
【问题描述】:

我有一个大型数据框(价格),其中包含一个长描述和与该描述相关的价格。我生成了另一个数据框(单词),它保留了那些长描述所具有的所有唯一单词。我要做的是从价格数据框中计算特定单词的价格总和,然后将其存储在单词数据框中,与单词在同一行中。

我得到了以下解决方案:

matches = (
    prices['TEXT'].str.extractall(f'({"|".join(words["WORD"])})')
    .rename(columns={0:'WORDS'})
    .rename_axis(['index', 'match'])
)

final = (
    prices.rename_axis('index')
    .join(matches)
    .groupby('WORDS', sort=False)['PRICE'].sum()
    .reset_index(name='SUM_PRICE')
)

但是输出的总和不正确(例如,列的总和是 19.6,所以没有条件总和应该更高,仍然为单词 'VINO' 计算 25.5):

    WORDS   MEAN_PRICE
0   VINO    25.5
1   ESPUMOSO    20.4
2   ROSE    13.3
3   GRADO   15.7
4   ALCOHOLICO  15.7

示例数据框:


prices = pd.DataFrame({'TEXT': ['VINO ESPUMOSO ROSE GRADO ALCOHOLICO 11.8 ACIDEZ VOLATIL 0.37 COSECHA 2013 EN CAJAS DE 06X750 ML SIN EMBALAR', 'VINO CON DENOMINACION DE ORIGEN ESPUMOSO SPARKLING ANGEL BRUT GRADO ALCOHOLICO 12.0 06BOTELLAS EN ENVASE DE 750 ML SIN EMBALAR', 'VINO ESPUMOSO CHARDONNAY PINOT NOIR EXTRA BR DE UVA, GR.ALC.12.80, ACIDEZ  VOL. 0.46 G/L.,CAJAS DE 6 BOLTELLAS DE 750 ML. SIN EMBALAR', 'VINO PINOT NOIR ROSE BRUT GA 12.0 AV 0.45 COSECHA 2013 CON DENOMINACION DE ORIGEN EN CAJAS CON BOTELLAS DE 6X750CC SIN EMBALAR', 'VINO ESPUMOSO ROSE GRADO ALCOHOLICO 11.8 ACIDEZ VOLATIL 0.37 COSECHA 2013 EN CAJAS DE 06X750 ML SIN EMBALAR VINO CON DENOMINACION DE ORIGEN ESPUMOSO SPARKLING ANGEL BRUT GRADO ALCOHOLICO 12.0 06BOTELLAS EN ENVASE DE 750 ML SIN EMBALAR VINO ESPUMOSO CHARDONNAY PINOT NOIR EXTRA BR DE UVA, GR.ALC.12.80, ACIDEZ  VOL. 0.46 G/L.,CAJAS DE 6 BOLTELLAS DE 750 ML. SIN EMBALAR VINO PINOT NOIR ROSE BRUT GA 12.0 AV 0.45 COSECHA 2013 CON DENOMINACION DE ORIGEN EN CAJAS CON BOTELLAS DE 6X750CC SIN EMBALAR'],
                       'PRICE': [6.33, 5.43, 2.79, 3.07, 1.96]})

words = pd.DataFrame({'WORD':['VINO', 'ESPUMOSO', 'ROSE', 'GRADO', 'ALCOHOLICO', '11.8', 'ACIDEZ', 'VOLATIL', '0.37', 'COSECHA', '2013', 'EN', 'CAJAS', 'DE', '06X750', 'ML', 'SIN', 'EMBALAR', 'CON', 'DENOMINACION', 'ORIGEN', 'SPARKLING', 'ANGEL', 'BRUT', '12.0', '06BOTELLAS', 'ENVASE', '750', 'CHARDONNAY', 'PINOT', 'NOIR', 'EXTRA', 'BR', 'UVA,', 'GR.ALC.12.80,', 'VOL.', '0.46', 'G/L.,CAJAS', '6', 'BOLTELLAS', 'ML.', 'GA', 'AV', '0.45', 'BOTELLAS', '6X750CC', ]})

非常感谢!

【问题讨论】:

  • 当单词在文本中出现多次时,您就会重复计算。你有一个预定义的单词列表,你想得到总和吗?这让事情变得简单多了。
  • 使用explode 还有一种更简单的方法来获得最终结果
  • 我认为这也可能是问题所在,但我尝试使用 prices[TEXT']=prices['TEXT'].str.split().apply(lambda x: ' '.join( list(set(x)))) 但它仍然不能正确计数
  • 爆炸解决方案听起来很棒。我查一下
  • @Erfan prices.join(prices['TEXT'].str.split().explode(), lsuffix='_*').drop_duplicates().groupby('TEXT')['PRICE'].sum()

标签: python pandas dataframe


【解决方案1】:

自从我回答了您的上一个问题以来,我很容易看出问题所在。您获得更高总和的原因是因为一个单词可以在一个句子中出现多次。所以在GroupBy之前使用DataFrame.drop_duplicates

matches = (
    prices['TEXT'].str.extractall(f'({"|".join(words["WORD"])})')
    .rename(columns={0:'WORDS'})
    .rename_axis(['index', 'match'])
)

final = (
    prices.rename_axis('index')
    .join(matches)
    .drop_duplicates()
    .groupby('WORDS', sort=False)['PRICE'].sum()
    .reset_index(name='SUM_PRICE')
)

            WORDS  SUM_PRICE
0            VINO      19.58
1        ESPUMOSO      16.51
2            ROSE      11.36
3           GRADO      13.72
4      ALCOHOLICO      13.72
5            11.8       8.29
6          ACIDEZ      11.08
7         VOLATIL       8.29
8            0.37       8.29
9         COSECHA      11.36
10           2013      11.36
11             EN      16.79
12          CAJAS      11.36
13             DE      19.58
14         06X750       8.29
15             ML      16.51
16            SIN      19.58
17        EMBALAR      19.58
18            CON      10.46
19         ORIGEN      10.46
20      SPARKLING       7.39
21          ANGEL       7.39
22           BRUT      10.46
23           12.0      10.46
24     06BOTELLAS       7.39
25            750      13.25
26     CHARDONNAY       4.75
27          PINOT       7.82
28           NOIR       7.82
29          EXTRA       4.75
30             BR       4.75
31           UVA,       4.75
32  GR.ALC.12.80,       4.75
33           VOL.       4.75
34           0.46       4.75
35     G/L.,CAJAS       4.75
36              6       7.82
37      BOLTELLAS       4.75
38             GA       5.03
39             AV       5.03
40           0.45       5.03
41       BOTELLAS       5.03

【讨论】:

  • 非常感谢您之前的回答和这个回答。如果在一个写着“VINOS”而不是“VINO etc...”的句子中找到一个单词,例如“VINO”,会发生什么?它会计算空格之间的单词还是仅在其他单词中查找单词?
最近更新 更多