仅用for循环与if语句实现DataFrame文本分组求和
问题:用for循环实现DataFrame按文本分组求和并添加列
原始DataFrame
| Text | Score |
|---|---|
| 'I love pizza!' | 2 |
| 'I love pizza!' | 1 |
| 'I love pizza!' | 3 |
| 'Python rules!' | 0 |
| 'Python rules!' | 5 |
期望输出
| Text | Score | Sum |
|---|---|---|
| 'I love pizza!' | 2 | 6 |
| 'I love pizza!' | 1 | 6 |
| 'I love pizza!' | 3 | 6 |
| 'Python rules!' | 0 | 5 |
| 'Python rules!' | 5 | 5 |
已知内置函数实现方式
可以用Pandas的groupby和merge快速实现:
df1 = df.groupby('Text')['Score'].sum().reset_index(name='Sum') df3 = df.merge(df1, on='Text', how='left')
需求限制
不能使用groupby、sum()这类内置聚合函数,仅允许通过for循环和if语句完成需求。
尝试的错误代码及问题
以下是尝试的代码:
def func(df): # NOTE, CANNOT USE LIST APPEND (as it is an in-built function). sum = 0 n = len(df['text']) # NEED TO WORK FOR-LOOP USING INTEGERS AND HENCE NEED LENGTH for i in range(0,n): exists = False #flag to track repeated values for j in range(i+1,n): if df['text'][i] == df['text'][j]: # IF TRUE, THEN THE 'TEXT' ROWS ARE SIMILAR I.E. GROUPED exists = True sum = df['score'][i] + df['score'][j] break; if not exists: sum += sum return sum df['Sum'] = func(df)
运行后所有行的Sum列都被赋值为10,结果不符合预期。问题出在:
- 仅累加了同组的两个元素,没有遍历所有同组行完成完整求和
- 最终返回的是单一值,导致整个列被覆盖为同一个数
- 逻辑错误,
if not exists时的sum += sum会错误累加
正确实现代码
核心思路是先通过循环统计每个文本对应的总分,存储在字典中,再循环给每行赋值:
def calculate_sum_column(df): # 存储每个文本对应的总分 text_total = {} n = len(df) # 第一步:统计每个文本的总分 for i in range(n): current_text = df['Text'].iloc[i] # 如果该文本还没统计过,遍历所有行求和 if current_text not in text_total: total = 0 for j in range(n): if df['Text'].iloc[j] == current_text: total += df['Score'].iloc[j] text_total[current_text] = total # 第二步:给每行添加Sum列的值,预先初始化列表避免使用append sum_list = [0] * n for i in range(n): sum_list[i] = text_total[df['Text'].iloc[i]] return sum_list # 赋值到DataFrame df['Sum'] = calculate_sum_column(df)
代码说明
- 用字典
text_total缓存每个文本的总分,避免重复计算(适配大数据量场景) - 第一次循环:对每个未统计过的文本,遍历所有行累加对应Score,存入字典
- 第二次循环:根据每行的Text,从字典中取出总分赋值到预初始化的列表,最后返回列表给DataFrame的Sum列
运行后即可得到符合预期的输出。
内容的提问来源于stack exchange,提问作者GaussEuler
相关产品推荐
相关产品推荐

