You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python单词与连续2-gram匹配求和问题求助

Python连续双词(2-gram)统计代码修正

示例CSV数据

NameLocationNumber
Andrew Platt AndrewA B C100
Steven Thunder AndrewA B C50
Jeff England StevenA B C30
Andrew England JeffA B C30

期望结果

{
    'Andrew': 180,
    'Platt': 100,
    'Steven': 80,
    'Jeff': 60,
    'England': 60,
    'Thunder':50,
    'Andrew Platt': 100,
    'Platt Andrew': 100,
    'Steven Thunder': 50,
    'Thunder Andrew': 50,
    'Jeff England': 30,
    'England Steven': 30,
    'Andrew England': 30,
    'England Jeff': 30
}

统计逻辑

  • 单词统计(one_words):统计每个单词所在行的Number总和,比如'Andrew'出现在第1、2、4行,总和为100+50+30=180
  • 连续双词统计(two_words):提取每行姓名中的连续相邻双词(即2-gram,如[a,b,c]生成[a,b]、[b,c]),统计每个连续双词对应行的Number总和,比如'Andrew Platt'仅出现在第1行,总和为100

尝试的代码

from collections import Counter
from itertools import combinations
import itertools
from pprint import pprint
import pandas as pd

data=[
    "Andrew Platt Andrew;100,",
    "Steven Thunder Andrew;50",
    "Jeff England Steven;30",
    "Andrew England Jeff;30"
    ]

one_words=Counter()
two_words=Counter()
df=[n.split(";") for n in data[0:]]
df=pd.DataFrame(df[1:],columns=df[0])
df.columns=('Name','Number')
df=df.replace('\,','',regex=True)
df['Number']=df.Number.replace('W','',regex=True)
items=" ".join(df.Name).split()

for item in set(items):
    one_words[item] += df.loc[df.Name.str.contains(item)].Number.astype('int').sum()
for two_word in combinations(items, 2):
    if len(set(two_word)) == 1:
        continue
    two_words[" ".join(two_word)] += df.loc[df.Name.str.contains(item)].Number.astype('int').sum()

pprint(one_words)
pprint(two_words)

当前结果

Counter({'Andrew': 180,
         'Platt': 100,
         'Steven': 80,
         'Jeff': 60,
         'England': 60,
         'Thunder': 50})
Counter({'Andrew Platt': 100,
         'Platt Andrew': 100,
         'Steven Thunder': 50,
         'Steven Andrew': 50,
         'Thunder Andrew': 50,
         'Jeff England': 30,
         'Jeff Steven': 30,
         'England Steven': 30,
         'Andrew England': 30,
         'Andrew Jeff': 30,
         'England Jeff': 30})

存在的问题

two_words部分错误生成了非连续双词(如'Steven Andrew'),需求是仅保留每行姓名中的连续相邻双词,而非全局所有单词的两两组合。

修正方案

问题核心是原代码用combinations(items, 2)生成了全局单词的所有两两组合,而非每行内的连续双词。需改为逐行处理,生成每行的连续双词并累加数值:

from collections import Counter
from pprint import pprint
import pandas as pd

data=[
    "Andrew Platt Andrew;100,",
    "Steven Thunder Andrew;50",
    "Jeff England Steven;30",
    "Andrew England Jeff;30"
    ]

one_words=Counter()
two_words=Counter()

# 处理数据生成DataFrame
df = [n.split(";") for n in data]
df = pd.DataFrame(df[1:], columns=df[0])
df.columns = ('Name','Number')
df = df.replace('\,','', regex=True)
df['Number'] = df['Number'].astype(int)

# 单词统计:逐行拆分单词并累加数值
for idx, row in df.iterrows():
    words = row['Name'].split()
    num = row['Number']
    for word in words:
        one_words[word] += num

# 连续双词统计:逐行生成相邻双词并累加数值
for idx, row in df.iterrows():
    words = row['Name'].split()
    num = row['Number']
    # 遍历到倒数第二个单词,与下一个单词组成连续双词
    for i in range(len(words)-1):
        two_word = f"{words[i]} {words[i+1]}"
        two_words[two_word] += num

# 合并单词与双词统计结果
result = dict(one_words)
result.update(two_words)
pprint(result)

代码说明

  1. 单词统计改为逐行处理,避免原代码str.contains可能出现的子串匹配错误
  2. 双词统计通过遍历每行单词列表的索引,生成仅连续相邻的双词,确保符合需求
  3. 合并两个统计结果,得到最终的完整字典

运行结果

{'Andrew': 180,
 'Andrew England': 30,
 'Andrew Platt': 100,
 'England': 60,
 'England Jeff': 30,
 'England Steven': 30,
 'Jeff': 60,
 'Jeff England': 30,
 'Platt': 100,
 'Platt Andrew': 100,
 'Steven': 80,
 'Steven Thunder': 50,
 'Thunder': 50,
 'Thunder Andrew': 50}

内容的提问来源于stack exchange,提问作者Peter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 12:20:23