如何避免Pandas中已分配值被覆盖并打印完整DataFrame
问题描述
在使用Pandas进行数据块分配时,当前实现能完成各分类的初始分配,但当某块容量已满、将同分类下待处理ID分配到新块时,之前已分配的旧值会被覆盖;另外,当前代码只能打印最后一个D块的分配结果,如何实现打印完整的新DataFrame?
现有代码实现
import pandas as pd data = pd.read_csv("database.csv") blocks = {"A": 5, "B": 30, "C": 50, "D": 100} for key, value in blocks.items(): print("For block " + key + " capacity is " + str(value)) while True: s = input("Which category to be allocated? ") dataFrame = data[data['Category'].str.contains(s)] if not dataFrame.empty: dataFrame['Block'] = key # for loop for Sr. Number spc = blocks[key] i = 1 for index, row in dataFrame.iterrows(): if i > spc: break dataFrame.loc[index, 'Sr.'] = str(i) i += 1 print(dataFrame) break print(dataFrame)
输入数据
Name,ID,Category ABC,2020,G WER,2021,M XCV,2022,T GFV,2034,M WEQ,2021,M WEW,2021,M WET,2021,M WEY,2021,M WLK,2021,M WYH,2021,M
预期输出
Name,ID,Category,Block, Sr. 1 WER 2021 M A 1 3 GFV 2034 M A 2 4 WEQ 2021 M A 3 5 WEW 2021 M A 4 6 WET 2021 M A 5 7 WEY 2021 M B 1 8 WLK 2021 M B 2 9 WYH 2021 M B 3
解决方案
原代码存在两个核心问题:
- 每次循环都从原始数据中提取整个分类的子集,修改后未同步回原始DataFrame,导致之前的分配结果被覆盖
- 最后仅打印了最后一次循环生成的子集变量,而非完整的处理结果
修改后的代码直接操作原始数据,仅处理未分配的行,保留所有分配记录:
import pandas as pd # 读取原始数据 data = pd.read_csv("database.csv") # 初始化Block和Sr.列,避免后续赋值报错 data['Block'] = pd.NA data['Sr.'] = pd.NA blocks = {"A": 5, "B": 30, "C": 50, "D": 100} for block_key, block_capacity in blocks.items(): print(f"For block {block_key} capacity is {block_capacity}") while True: category = input("Which category to be allocated? ") # 筛选当前分类下未分配Block的行 unassigned_rows = data[(data['Category'] == category) & data['Block'].isna()] if not unassigned_rows.empty: # 取最多block_capacity条未分配数据 assign_count = min(block_capacity, len(unassigned_rows)) target_indices = unassigned_rows.index[:assign_count] # 更新原始数据的Block和序号 data.loc[target_indices, 'Block'] = block_key data.loc[target_indices, 'Sr.'] = range(1, assign_count + 1) # 打印当前块的分配结果 print(data.loc[target_indices]) break else: print(f"该分类{category}已无未分配数据,请重新选择") # 打印完整的已分配结果 print("\n=== 完整分配结果 ===") print(data.dropna(subset=['Block']))
关键修改点
- 初始化列:提前创建
Block和Sr.列,避免赋值时出现KeyError - 筛选未分配行:每次只处理当前分类下还没分配Block的行,彻底解决旧值被覆盖的问题
- 直接修改原始数据:所有分配操作都在原始
data上进行,保留所有历史分配记录 - 完整结果输出:最后通过
dropna筛选出已分配的行,打印完整结果
内容的提问来源于stack exchange,提问作者Adam Burri
相关产品推荐
相关产品推荐

