Pandas DataFrame修改单单元格集合时所有单元格同步更新问题
问题场景
构建了一个所有单元格存储仅含元素"O"的集合的Pandas DataFrame,初始结构如下:
1 2 3 4 4 {O} {O} {O} {O} 3 {O} {O} {O} {O} 2 {O} {O} {O} {O} 1 {O} {O} {O} {O}
需求为将列表['A11\n', '\n', 'B21\n', '\n', 'P31\n']中的对应字母添加到指定坐标的单元格集合中,例如字母B需添加到索引为1、列名为2的单元格集合内。
使用的实现代码如下(代码中lines即为上述列表):
for line in lines: if line[0] == "A": width = int(line[1]) height = int(line[2]) board.at[height, width].add("A")
预期执行后仅索引为1、列名为1的单元格集合新增"A"元素,其余单元格保持{O}不变,预期结果如下:
1 2 3 4 4 {O} {O} {O} {O} 3 {O} {O} {O} {O} 2 {O} {O} {O} {O} 1 {A,O} {O} {O} {O}
实际运行后所有单元格的集合均新增了"A"元素,异常结果如下:
1 2 3 4 4 {A, O} {A, O} {A, O} {A, O} 3 {A, O} {A, O} {A, O} {A, O} 2 {A, O} {A, O} {A, O} {A, O} 1 {A, O} {A, O} {A, O} {A, O}
故障原因
问题出在DataFrame的初始化逻辑:集合是Python可变引用类型,如果你初始化时使用了引用复制的写法(例如[{'O'}]*4、外层再嵌套列表乘法生成二维结构),会导致所有单元格存储的是同一个集合对象的内存引用,而非各自独立的集合实例。
此时调用board.at[height, width].add("A")修改的是这个全局共享的集合对象,所有单元格引用的都是同一个对象,自然会同步显示新增的"A"元素。
修复方案
初始化DataFrame时,为每个单元格单独创建独立的集合实例,禁止用乘法批量复制可变对象的引用。
- 错误初始化写法(会触发该bug):
# 列表乘法复制的是引用,所有单元格共享同一个集合 board = pd.DataFrame([[{'O'}]*4]*4, index=[4,3,2,1], columns=[1,2,3,4])
- 正确初始化写法:
# 两层循环逐单元格生成新的独立集合 board = pd.DataFrame( [[{'O'} for _ in range(4)] for _ in range(4)], index=[4,3,2,1], columns=[1,2,3,4] )
按上述方式初始化后,再运行元素添加逻辑,即可得到预期的单单元格修改效果。
内容的提问来源于stack exchange,提问作者programur
相关产品推荐
相关产品推荐

