如何有效地改变数组中的某些数值?

alv*_*vas 1 python arrays numpy

给出一个初始的二维数组:

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]]
Run Code Online (Sandbox Code Playgroud)

目标是将数组内的一些随机值乘以随机百分比.可以说只有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]]
Run Code Online (Sandbox Code Playgroud)

我试过这样做:

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
Run Code Online (Sandbox Code Playgroud)

这适用于2D数组,但有可能同一个值突变多次=(

我不认为这是有效的,它只适用于2D阵列.

有没有办法为任何形状的阵列做更多有效的"突变"?

"突变"可以选择哪个值没有限制,但"突变"的数量应该严格保持用户指定的数量.

Mad*_*ist 5

一种相当简单的方法是使用数组的ravel视图.您可以一次生成所有数字,并且更容易保证在一次调用中不会处理两次相同的索引:

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
Run Code Online (Sandbox Code Playgroud)

array_anyd.reshape(-1)赞成使用,array_anyd.ravel()因为根据文档,前者不太可能制作无意的副本.

当然,这仍然是一种可能性.如果需要,您可以添加额外的检查以进行回写.一种更有效的方法是使用np.unravel_index避免创建视图开头:

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
Run Code Online (Sandbox Code Playgroud)

无需返回任何内容,因为修改是就地完成的.通常,这些功能不会返回任何东西.例如,见list.sortVS sorted.