Как удалить дубликаты и заставить элементы в массиве numpy быть уникальными, используя заданный диапазон? - PullRequest
1 голос
/ 25 апреля 2019

В случае дифференциальной эволюции, во время мутации, наиболее часто используемая формула имеет вид

arr[a] = (arr[b] + M * (arr[c] - arr[d])) % arr.shape[1]

Где
arr - это двумерный массив, состоящий из неотрицательных целых чисел, так что все элементы в каждой строке уникальны,
a представляет каждую строку arr,
M - константа мутации в диапазоне от 0 до 2 и
b, c и d - 3 уникальных случайных числа.

Однако, используя эту формулу, я вижу, что arr[a] имеет повторяющиеся значения, основанные на значениях arr[b], arr[c] и arr[d]. Я хочу, чтобы в arr[a] были только уникальные номера. Как это возможно с помощью Numpy?

* * Например, тысяча двадцать-три
arr[a] = [2, 8, 4, 9, 1, 6, 7, 3, 0, 5]
arr[b] = [3, 5, 1, 2, 9, 8, 0, 6, 7, 4]
arr[c] = [2, 3, 8, 4, 5, 1, 0, 6, 9, 7]
arr[d] = [6, 1, 9, 2, 7, 5, 8, 0, 3, 4]

При применении формулы arr[a] становится [9, 7, 0, 4, 7, 4, 2, 2, 3, 7]. Но я хочу, чтобы в нем были только уникальные числа от 0 до arr.shape[1]. Я открыт для изменения функции мутации, если это необходимо, если M, arr [b], arr [c] и arr [d] все используются осмысленно.

Ответы [ 3 ]

1 голос
/ 25 апреля 2019

Это довольно другой подход к проблеме, но, поскольку вы, похоже, работаете с перестановками, я не уверен, что числовые различия имеют такое значение.Однако вы можете увидеть проблему с точки зрения перестановок, то есть переупорядочения векторов.Вместо разницы между двумя векторами вы можете рассмотреть перестановку, которая переносит вас от одного вектора к другому, и вместо добавления двух векторов вы можете рассмотреть возможность применения перестановки к вектору.Если вы хотите иметь параметр M, возможно, это может быть количество раз, когда вы применяете перестановку?(при условии, что это неотрицательное целое число)

Вот основная идея того, как вы могли бы реализовать это:

import numpy as np

# Finds the permutation that takes you from vector a to vector b.
# Returns a vector p such that a[p] = b.
def permutation_diff(a, b):
    p = np.zeros_like(a)
    p[a] = np.arange(len(p), dtype=p.dtype)
    return p[b]

# Applies permutation p to vector a, m times.
def permutation_apply(a, p, m=1):
    out = a.copy()
    for _ in range(m):
        out = out[p]
    return out

# Combination function
def combine(b, c, d, m):
    return permutation_apply(b, permutation_diff(d, c), m)

# Test
b = np.array([3, 5, 1, 2, 9, 8, 0, 6, 7, 4])
c = np.array([2, 3, 8, 4, 5, 1, 0, 6, 9, 7])
d = np.array([6, 1, 9, 2, 7, 5, 8, 0, 3, 4])
m = 1
a = combine(b, c, d, m)
print(a)
# [2 7 0 4 8 5 6 3 1 9]

Поскольку вы работаете со многими векторами, расположенными в матрице, выможет предпочесть векторизованные версии вышеуказанных функций.Вы можете получить это с чем-то вроде этого (здесь я предполагаю, что M является фиксированным параметром для всего алгоритма, а не для отдельного человека):

import numpy as np

# Finds the permutations that takes you from vectors in a to vectors in b.
def permutation_diff_vec(a, b):
    p = np.zeros_like(a)
    i = np.arange(len(p))[:, np.newaxis]
    p[i, a] = np.arange(p.shape[-1], dtype=p.dtype)
    return p[i, b]

# Applies permutations in p to vectors a, m times.
def permutation_apply_vec(a, p, m=1):
    out = a.copy()
    i = np.arange(len(out))[:, np.newaxis]
    for _ in range(m):
        out = out[i, p]
    return out

# Combination function
def combine_vec(b, c, d, m):
    return permutation_apply_vec(b, permutation_diff_vec(d, c), m)

# Test
np.random.seed(100)
arr = np.array([[2, 8, 4, 9, 1, 6, 7, 3, 0, 5],
                [3, 5, 1, 2, 9, 8, 0, 6, 7, 4],
                [2, 3, 8, 4, 5, 1, 0, 6, 9, 7],
                [6, 1, 9, 2, 7, 5, 8, 0, 3, 4]])
n = len(arr)
b = arr[np.random.choice(n, size=n)]
c = arr[np.random.choice(n, size=n)]
d = arr[np.random.choice(n, size=n)]
m = 1
arr[:] = combine_vec(b, c, d, m)
print(arr)
# [[3 6 0 2 5 1 4 7 8 9]
#  [6 1 9 2 7 5 8 0 3 4]
#  [6 9 2 3 5 0 4 1 8 7]
#  [2 6 5 4 1 9 8 0 7 3]]
1 голос
/ 25 апреля 2019

Попробуйте сделать это:

list(set(arr[a])) 
0 голосов
/ 25 апреля 2019

Вот пример того, что можно сделать:

array = np.array([9, 7, 0, 4, 7, 4, 2, 2, 3, 7])
shape = array.shape[0]
array = list(set(array))
for i in range(shape):
    if i not in array:
        array.append(i)
array = np.array(array)

Если вы хотите заполнить индекс чисел дубликатами, логика немного отличается.Но идея такова.Я надеюсь, что помог тебе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...