如何高效批量设置Pandas DataFrame中指定位置的值?
问题
我有一个大型DataFrame,需要将大量指定位置设置为某个值。目前通过循环逐个设置这些值,速度极慢:
import pandas as pd import numpy as np # 大型DataFrame column_names = np.array(range(100)) np.random.shuffle(column_names) row_names = np.array(range(100)) np.random.shuffle(row_names) df = pd.DataFrame(columns=column_names, index=row_names) # 待设置的索引值 ix = np.random.randint(0, 100,1000) # 待设置的列值 iy = np.random.randint(0, 100,1000) # 逐个将指定位置设为1 for k in range(len(ix)): df.loc[ix[k], iy[k]]=1
上述循环在我的机器上耗时0.35秒。尝试用df.loc[ix, iy]=1仅需0.035秒,但结果不正确——它会把ix和iy的所有组合对应的位置都设为1。想找同样高效的批量设置方法,无需逐个遍历位置。
高效批量设置方法
方法1:元组列表精准索引
直接将ix和iy配对成(row, column)元组的列表,传入df.loc即可实现精准赋值,速度和批量操作一致:
df.loc[list(zip(ix, iy))] = 1
该方式严格按照每一组(ix[k], iy[k])的位置赋值,和循环逻辑完全一致,不会产生笛卡尔积的错误。
方法2:直接操作底层Numpy数组
利用DataFrame的底层Numpy数组操作,性能最优:
# 转换为整数位置(适配打乱的索引/列名) row_pos = df.index.get_indexer(ix) col_pos = df.columns.get_indexer(iy) # 直接修改底层数组 df.values[row_pos, col_pos] = 1
这种方式绕开Pandas索引层,直接对Numpy数组赋值,速度接近纯Numpy操作,适合超大型数据集。
方法3:Series构造更新序列
若需要保留原有非NaN值,可构造Series后用update方法批量更新:
update_series = pd.Series(1, index=pd.MultiIndex.from_arrays([ix, iy])) df.update(update_series.unstack(fill_value=np.nan))
此方法逻辑清晰,但性能略逊于前两种。
内容的提问来源于stack exchange,提问作者Botond
相关产品推荐
相关产品推荐

