Pandas DataFrame在for循环中无法更新,随机位翻转失败如何解决?
解决Pandas DataFrame随机位翻转无更新的问题
问题重现
尝试在100万行、8列的0/1 Pandas DataFrame中随机翻转10个位,但无论用at/loc还是异或、条件判断逻辑,最终检查data_in和data的差值总和始终为0,DataFrame看似未发生更新。
原翻转代码:
import pandas as pd import numpy as np import random data_in = pd.read_csv('input.csv') data = data_in # 此处为问题核心 for i in range(0, 10): a = random.randint(0, 999999) b = random.randint(0, 7) b = str(b) # 使用异或翻转 data.at[a, b] = data.at[a, b] ^ 1 # 或者用条件判断逻辑 # if (data.loc[a, b] == 1): # data.loc[a, b] = 0 # else: # data.loc[a, b] = 1
检查代码:
c = abs(data_in-data) c = c.sum(axis=0) c = c.sum() # 结果始终为0
问题原因
- 引用赋值而非拷贝:
data = data_in并没有创建新的DataFrame对象,只是让data指向了和data_in相同的内存地址。修改data的同时会同步修改data_in,最终两者完全一致,差值自然为0。 - (次要)若CSV读取后列数据类型为
object,异或操作可能无法正确生效,但核心问题仍是引用赋值导致的对象同步。
解决方案
1. 修正循环方法(基础版)
先对原DataFrame做深拷贝,确保data是独立对象:
import pandas as pd import numpy as np import random data_in = pd.read_csv('input.csv') data = data_in.copy() # 改为深拷贝 for i in range(0, 10): a = random.randint(0, 999999) b = random.randint(0, 7) col_name = str(b) # 若数据类型不是int,先转换 # data[col_name] = data[col_name].astype(int) data.at[a, col_name] = data.at[a, col_name] ^ 1
此时运行检查代码,c会等于10(对应翻转的10个位)。
2. 高效批量处理(推荐,避免循环)
100万行的DataFrame用for循环效率极低,推荐用NumPy向量化操作直接批量修改:
import pandas as pd import numpy as np data_in = pd.read_csv('input.csv') data = data_in.copy() # 生成10个随机翻转位置 n_flips = 10 rows = np.random.randint(0, len(data), size=n_flips) cols = np.random.randint(0, 8, size=n_flips) # 转为NumPy数组直接修改,比循环效率提升百倍 data_np = data.to_numpy() data_np[rows, cols] ^= 1 data = pd.DataFrame(data_np, columns=data.columns)
验证结果
运行检查代码:
c = abs(data_in - data).sum().sum() print(c) # 输出10,符合预期
内容的提问来源于stack exchange,提问作者Ebs
相关产品推荐
相关产品推荐

