基于特定规则转换DataFrame中0/1值的Pandas实现求助
Pandas 高效实现方法
直接用Pandas的矢量化操作就能搞定,完全不用循环,效率拉满。核心思路是先把所有1转成0,再用移位操作标记出需要转1的0的位置。
步骤分解
- 复制原始DataFrame,先把所有1替换成0,作为基础结果。
- 用
shift()方法分别获取每行的前一行、后一行取值,标记出哪些位置的前后存在1。 - 结合原始DataFrame的0值位置,生成最终需要转1的掩码。
- 将掩码对应的位置设为1。
代码示例
import pandas as pd # 示例原始DataFrame df = pd.DataFrame({ 'A': [0,1,1,0,0,0], 'B': [0,0,1,1,0,0], 'C': [1,1,0,0,1,0], 'D': [0,0,0,1,1,1] }) # 1. 初始化结果,将所有1转为0 result = df.copy() result[df == 1] = 0 # 2. 生成前后有1的标记 prev_has_1 = df.shift(1).fillna(0).astype(bool) # 前一行是1 next_has_1 = df.shift(-1).fillna(0).astype(bool) # 后一行是1 # 3. 生成掩码:原始是0,且前后至少有一个是1 mask = (prev_has_1 | next_has_1) & (df == 0) # 4. 把掩码位置设为1 result[mask] = 1 print(result)
运行后得到的目标结果:
A B C D 0 1 0 0 0 1 0 1 0 0 2 1 0 1 1 3 1 0 1 0 4 0 1 0 0 5 0 0 1 0
处理列方向的连续1块
如果你的需求是处理行内连续的1块(即列方向的前后位置),只需给shift()加上axis=1参数,修改后的掩码代码如下:
prev_has_1 = df.shift(axis=1).fillna(0).astype(bool) # 前一列是1 next_has_1 = df.shift(-1, axis=1).fillna(0).astype(bool) # 后一列是1 mask = (prev_has_1 | next_has_1) & (df == 0)
这种方法完全依赖Pandas的底层优化,比循环快几个量级,不管DataFrame规模多大都能高效处理。
内容的提问来源于stack exchange,提问作者HbNIW NIW
相关产品推荐
相关产品推荐

