Pandas使用map()修改单列时其他列被改动的解决方法
如何仅修改Pandas DataFrame中的单列值(避免关联列被修改)
我尝试修改Pandas DataFrame的单列值,但使用map()函数时,另一无关列的数值也发生了变化,怎么实现只改单列?以下是我的代码、当前输出及期望输出:
columns = [[[776, 114, 67, 47], [776, 167, 67, 52], [776, 224, 67, 62],[776, 291, 67, 58],[776, 355, 67, 52]], [[849, 114, 76, 48], [849, 167, 76, 52],[849, 225, 76, 61],[849, 291, 76, 59],[849, 355, 75, 53]], [[930, 115, 113, 47], [930, 168, 113, 51], [930, 225, 113, 61], [930, 292, 113, 58], [930, 355, 113, 53]]] dic = {'A': columns[0], 'B': columns[0], 'C': columns[1], 'D': columns[2]} df = pd.DataFrame.from_dict(dic) def subs(x): x[0] = 230 x[2] = 533 return x df['A'] = df['A'].map(subs)
当前输出
A B C D 0 [230, 114, 533, 47] [230, 114, 533, 47] [849, 114, 76, 48] [930, 115, 113, 47] 1 [230, 167, 533, 52] [230, 167, 533, 52] [849, 167, 76, 52] [930, 168, 113, 51] 2 [230, 224, 533, 62] [230, 224, 533, 62] [849, 225, 76, 61] [930, 225, 113, 61] 3 [230, 291, 533, 58] [230, 291, 533, 58] [849, 291, 76, 59] [930, 292, 113, 58] 4 [230, 355, 533, 52] [230, 355, 533, 52] [849, 355, 75, 53] [930, 355, 113, 53]
期望输出
A B C D 0 [230, 114, 533, 47] [776, 114, 67, 47] [849, 114, 76, 48] [930, 115, 113, 47] 1 [230, 167, 533, 52] [776, 167, 67, 52] [849, 167, 76, 52] [930, 168, 113, 51] 2 [230, 224, 533, 62] [776, 224, 67, 62] [849, 225, 76, 61] [930, 225, 113, 61] 3 [230, 291, 533, 58] [776, 291, 67, 58] [849, 291, 76, 59] [930, 292, 113, 58] 4 [230, 355, 533, 52] [776, 355, 67, 52] [849, 355, 75, 53] [930, 355, 113, 53]
问题原因
核心是可变对象的引用传递:
- 创建字典时,
'A'和'B'都指向了同一个列表对象columns[0],Python中列表是可变对象,赋值操作只是传递引用,不是复制内容。 subs函数直接修改了传入的列表x的元素,这会直接修改内存中该列表的原始数据,导致所有指向这个列表的列(也就是'B'列)同步变化。
解决方案
方案1:创建DataFrame时复制列表,让列指向独立对象
修改字典定义,对columns[0]进行深度复制,确保'A'和'B'使用不同的列表实例:
# 复制每个子列表,避免引用同一对象 dic = {'A': [lst.copy() for lst in columns[0]], 'B': columns[0], 'C': columns[1], 'D': columns[2]} df = pd.DataFrame.from_dict(dic) def subs(x): x[0] = 230 x[2] = 533 return x df['A'] = df['A'].map(subs)
方案2:修改subs函数,返回新列表而非修改原对象
不修改原始列表,创建副本并修改后返回,避免影响原对象:
def subs(x): # 创建原列表的副本,修改副本后返回 new_x = x.copy() new_x[0] = 230 new_x[2] = 533 return new_x df['A'] = df['A'].map(subs)
两种方案都能得到期望输出:方案2更直接,适合仅需修改单列的场景;方案1更彻底,适合需要长期保证列独立性的场景。
内容的提问来源于stack exchange,提问作者Hugo Pinho
相关产品推荐
相关产品推荐

