简体   繁体   English

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

[英]How to efficiently mutate certain num of values in an array?

Given an initial 2-D array: 给定初始二维数组:

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]]

The goal is to multiply some random values inside the array by a random percentage. 目标是将数组内的一些随机值乘以随机百分比。 Lets say only 3 random numbers get replaced by a random multipler, we should get something like this: 假设只有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]]

I've tried doing this: 我尝试这样做:

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

And that works for 2D arrays but there's chance that the same value is mutated more than once =( 这适用于2D数组,但相同的值可能会多次被突变==

And I don't think that's efficient and it only works on 2D array. 而且我不认为这是有效的,它仅适用于2D阵列。

Is there a way to do such "mutation" for array of any shape and more efficiently? 有没有一种方法可以更有效地对任何形状的数组进行这种“变异”?

There's no restriction of which value the "mutation" can choose from but the number of "mutation" should be kept strict to the user specified number. 对于“变异”可以选择哪个值没有任何限制,但是“变异”的数量应严格限制在用户指定的数量之内。

One fairly simple way would be to work with a raveled view of the array. 一种相当简单的方法是使用数组的斜视图。 You can generate all your numbers at once that way, and make it easier to guarantee that you won't process the same index twice in one call: 您可以通过这种方式一次生成所有数字,并可以更轻松地保证一次调用不会处理相同的索引两次:

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

I use array_anyd.reshape(-1) in favor of array_anyd.ravel() because according to the docs , the former is less likely to make an inadvertent copy. 我使用array_anyd.reshape(-1)来支持array_anyd.ravel()因为根据docs ,前者不太可能无意间复制。

The is of course still such a possibility. 当然仍然是这样的可能性。 You can add an extra check to write back if you need to. 您可以根据需要添加额外的支票以写回。 A more efficient way would be to use np.unravel_index to avoid creating a view to begin with: 一种更有效的方法是使用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

There is no need to return anything because the modification is done in-place. 由于修改是就地完成的,因此无需返回任何内容。 Conventionally, such functions do not return anything. 按照惯例,此类函数不返回任何内容。 See for example list.sort vs sorted . 参见例如list.sortsorted

Using shuffle instead of random_choice , this would be a different solution. 使用shuffle代替random_choice ,这将是另一种解决方案。 It works on an array of any shape. 它可以处理任何形状的数组。

def mutate(arrayIn, num_changes):
    mult = np.zeros(arrayIn.ravel().shape[0])
    mult[:num_changes] = np.random.uniform(0,1,num_changes)
    np.random.shuffle(mult)
    mult = mult.reshape(arrayIn.shape)
    arrayIn = arrayIn + mult*arrayIn
    return arrayIn

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM