Skip to main content
 首页 » 编程设计

python之如何有效地改变数组中一定数量的值

2025年05月04日21开发

给定一个初始二维数组:

initial = [ 
 [0.6711999773979187, 0.1949000060558319], 
 [-0.09300000220537186, 0.310699999332428], 
 [-0.03889999911189079, 0.2736999988555908], 
 [-0.6984000205993652, 0.6407999992370605], 
 [-0.43619999289512634, 0.5810999870300293], 
 [0.2825999855995178, 0.21310000121593475], 
 [0.5551999807357788, -0.18289999663829803], 
 [0.3447999954223633, 0.2071000039577484], 
 [-0.1995999962091446, -0.5139999985694885], 
 [-0.24400000274181366, 0.3154999911785126]] 

目标是将数组中的一些随机值乘以随机百分比。假设只有 3 个随机数被随机乘法器替换,我们应该得到这样的结果:

output = [ 
 [0.6711999773979187, 0.52], 
 [-0.09300000220537186, 0.310699999332428], 
 [-0.03889999911189079, 0.2736999988555908], 
 [-0.6984000205993652, 0.6407999992370605], 
 [-0.43619999289512634, 0.5810999870300293], 
 [0.84, 0.21310000121593475], 
 [0.5551999807357788, -0.18289999663829803], 
 [0.3447999954223633, 0.2071000039577484], 
 [-0.1995999962091446, 0.21], 
 [-0.24400000274181366, 0.3154999911785126]] 

我试过这样做:

def mutate(array2d, num_changes): 
    for _ in range(num_changes): 
        row, col = initial.shape 
        rand_row = np.random.randint(row) 
        rand_col = np.random.randint(col) 
        cell_value = array2d[rand_row][rand_col]  
        array2d[rand_row][rand_col] =  random.uniform(0, 1) * cell_value 
    return array2d 

这适用于二维数组,但相同的值有可能发生不止一次的变异 =(

而且我不认为这是有效的,它只适用于二维数组。

有没有办法更有效地对任何形状的数组进行这种“突变”?

对于“变异”可以选择的值没有限制,但“变异”的数量应严格保持在用户指定的数量。

请您参考如下方法:

一种相当简单的方法是使用数组的散乱 View 。您可以通过这种方式一次生成所有数字,并且更容易保证您不会在一次调用中两次处理相同的索引:

def mutate(array_anyd, num_changes): 
    raveled = array_anyd.reshape(-1) 
    indices = np.random.choice(raveled.size, size=num_changes, replace=False) 
    values = np.random.uniform(0, 1, size=num_changes) 
    raveled[indices] *= values 

我使用 array_anyd.reshape(-1) 而不是 array_anyd.ravel() 因为根据 docs , 前者不太可能无意中复制。

当然还有这种可能。如果需要,您可以添加额外的支票以回写。一种更有效的方法是使用 np.unravel_index避免创建一个 View 开始:

def mutate(array_anyd, num_changes): 
    indices = np.random.choice(array_anyd.size, size=num_changes, replace=False) 
    indices = np.unravel_indices(indices, array_anyd.shape) 
    values = np.random.uniform(0, 1, size=num_changes) 
    raveled[indices] *= values 

不需要返回任何东西,因为修改是就地完成的。按照惯例,此类函数不返回任何内容。参见例如 list.sort 与 sorted。