Home > Net >  How do you replace random values in a list of variable dimensioned and variable sized ndarrays
How do you replace random values in a list of variable dimensioned and variable sized ndarrays

Time:03-31

I would like to take a list of unknown size, containing ndarrays, where each ndarray could have any dimension and size independent from the the others, and replace values at random spots in this entire data structure.

I can create an index for a random spot by doing this:

    for w in weights:
        number_of_weights  = w.size()

The problem is how I would go about inserting without having to recursively check that I am at the last dimension while adding to a counter until it is greater than the index and decrementing another counter to know where in the last dimension I am inserting.

CodePudding user response:

I am already using Tensorflow, so I came up with a solution that uses it.

The idea was to reshape the multidimensional ndarray that would get the replacement into a flat array after finding what index in the list it was, and then reshaping it back to the original shape after the replacement, and replacing it's old copy in the list.

Please note that this is not as efficient as it could be due to multiple iterations of index keeping and replacements. If it becomes an issue, the indices could be pre-computed, and the ndarrays replaced a max of once instead of every iteration of the loop below.

def mutate(weights, n_mutations):
    number_of_weights = 0
    a = 0
    b = 0
    for i in weights:
        number_of_weights  = i.size
        a = min(a, i.min())
        b = max(b, i.min())
    n_mutations = min(number_of_weights, n_mutations)

    row = 0
    count = weights[row].size - 1
    for i in range(n_mutations):
        index = random.randrange(0, number_of_weights)
        index_const = index
        while count < index_const:
            index -= (weights[row].size   1)
            row  = 1
            count  = weights[row].size

        new_weight = random.uniform(a, b - 1)
        shape = weights[row].shape
        flat_row = tf.reshape(weights[row], [-1]).numpy()
        flat_row[index] = new_weight
        new_row = tf.reshape(flat_row, shape).numpy()
        weights[row] = new_row
        row = 0
        count = 0
    return weights

CodePudding user response:

I found out about a solution that uses the ravel() function.

def get_row_and_index(weights, index):
    index_const = index
    row = 0
    count = weights[row].size - 1
    while count < index_const:
        index -= weights[row].size
        row  = 1
        count  = weights[row].size
    return row, index
def mutate_weights(weights, n_mutations):
    new_weights = copy.deepcopy(weights)
    number_of_weights = 0
    a = 0
    b = 0
    for i in new_weights:
        number_of_weights  = i.size
        a = min(a, i.min())
        b = max(b, i.max())
    n_mutations = min(number_of_weights, n_mutations)

    for i in range(n_mutations):
        index = random.randrange(0, number_of_weights)
        row, index = get_row_and_index(new_weights, index)
        new_weight = random.uniform(a, b)
        flat_row = new_weights[row].ravel()
        flat_row[index] = new_weight
  • Related