如何修正Python Pandas生成的DataFrame重复行索引问题
解决Pandas循环创建DataFrame时索引无法连续递增的问题
问题根源
你当前的代码在循环中每次都新建一个仅包含一行数据的DataFrame,所以每次输出的索引都是0,而且最终df变量只会保留最后一次循环生成的结果,自然无法得到连续递增的索引。
最优解决方案:先收集数据再一次性生成DataFrame
效率最高的做法是先把所有商品和价格数据收集到一个列表中,循环结束后再统一创建DataFrame,Pandas会自动生成连续的整数索引。
修改后的代码:
import re import pandas as pd # 模拟你的收据行数据(实际使用时替换为你的原始数据) receipt_lines = [ "BAGGED KALE 2.94", "ORG PARSLEY 1.98", "ORG BASIL 1.98", "ORG BASIL 1.98", "ORG BAY LEAV 1.98", "GV ZUC BLND 1.48" ] # 初始化空列表存储所有数据 data_list = [] for line in receipt_lines: # 提取商品名称 res = re.sub('[^a-zA-z]+', ' ', line) item_name = ' '.join([w for w in res.split() if len(w) > 1]) # 提取价格 price_list = re.findall('\d+\.\d+', line) for price in price_list: # 将每组数据以字典形式加入列表 data_list.append({'Item': item_name, 'Price': price}) # 一次性生成DataFrame df = pd.DataFrame(data_list) # 转换价格为数值类型 df['Price'] = pd.to_numeric(df['Price'], errors='coerce') # 输出结果 print(df) print(df.info())
输出结果(符合你的期望)
Item Price 0 BAGGED KALE 2.94 1 ORG PARSLEY 1.98 2 ORG BASIL 1.98 3 ORG BASIL 1.98 4 ORG BAY LEAV 1.98 5 GV ZUC BLND 1.48
备选方案:循环中逐步拼接DataFrame(不推荐,效率较低)
如果一定要在循环中逐步构建DataFrame,可以使用pd.concat,并设置ignore_index=True来重置索引:
import re import pandas as pd receipt_lines = [ "BAGGED KALE 2.94", "ORG PARSLEY 1.98", "ORG BASIL 1.98", "ORG BASIL 1.98", "ORG BAY LEAV 1.98", "GV ZUC BLND 1.48" ] # 初始化空DataFrame df = pd.DataFrame() for line in receipt_lines: res = re.sub('[^a-zA-z]+', ' ', line) item_name = ' '.join([w for w in res.split() if len(w) > 1]) price_list = re.findall('\d+\.\d+', line) for price in price_list: temp_df = pd.DataFrame({'Item': [item_name], 'Price': [price]}) temp_df['Price'] = pd.to_numeric(temp_df['Price'], errors='coerce') # 拼接临时DataFrame并重置索引 df = pd.concat([df, temp_df], ignore_index=True) print(df) print(df.info())
关键说明
- 优先选择先收集数据再一次性生成DataFrame的方式,因为循环拼接DataFrame会不断创建新对象,数据量大时性能很差。
ignore_index=True参数会让Pandas在拼接后重新生成连续的索引,避免保留原DataFrame的重复索引。
内容的提问来源于stack exchange,提问作者GILBERT KELLER
相关产品推荐
相关产品推荐

