Удалить наименьшее число p% из нескольких массивов numpy - PullRequest
0 голосов
/ 17 апреля 2020

надеюсь, что все в порядке в эти пандемии COVID-19 c раз! У меня есть проблема, которая заключается в следующем:

У меня есть несколько numpy многомерных массивов, которые имеют разные случайные числа в них. Теперь мне нужно удалить числа наименьшей величины из всех различных массивов numpy. Это аналогично тому, как каким-то образом сохранять все числа из нескольких массивов в одномерный массив, а затем удалять из них числа наименьшей величины.

Я знаю, как это сделать для отдельного массива numpy. Код выглядит следующим образом:

# Define 3 numpy arrays-
x = np.random.uniform(low = -1000, high = 1000, size = (3, 3, 64))
y = np.random.uniform(low = -1000, high = 1000, size = (3, 3, 128))
z = np.random.uniform(low = -1000, high = 1000, size = (3, 3, 256))

x.shape, y.shape, z.shape
# ((3, 3, 64), (3, 3, 128), (3, 3, 256))

# Print a slice of 'x'-
# x[:,:, 0]


# Compute absolute values of 'x'-
x_mod = np.abs(x)

# Remove smallest (p = 10%) of absolute magnitude numbers to zero-
x_mod[x_mod < np.percentile(x_mod, 10)] = 0

# For removed numbers, have zero, otherwise the original values from 'x'-
x_fin = np.where(x_mod == 0, 0, x)

Есть ли способ убрать веса наименьшей величины, учитывая все массивы numpy: x, y и z (для данного примера)?

Я использую Python 3.8 вместе с numpy 1.18.

Спасибо!

РЕДАКТИРОВАТЬ:

Текущий способ решения этой проблемы заключается в следующем:

# Create a numpy array concatenating all numpy arrays-
a = np.concatenate((x, y, z), axis = None)

a.shape
(4032,)

# Create absolute value for the numbers-
a_mod = np.abs(a)

# Remove the smallest 10% of magnitude based numbers-
a_mod[a_mod < np.percentile(a_mod, 10)] = 0

# Final array which has 0 for pruned numbers and the original number otherwise-
a_fin = np.where(a_mod == 0, 0, a)

# Take slices from 1-D numpy array and re-create different numpy arrays
# from above-
x_new = a_mod[:576].reshape(3, 3, 64)
y_new = a_mod[576:1728].reshape(3, 3, 128)
z_new = a_mod[1728:].reshape(3, 3, 256)

x_new.shape, y_new.shape, z_new.shape                                  
# ((3, 3, 64), (3, 3, 128), (3, 3, 256))

Есть ли лучший способ добиться этого, потому что мне нужно обработать около 20 или более массивов numpy, а затем создание абсолютных срезов, таких как [576: 1728], становится подверженным ошибкам и не масштабируется !

1 Ответ

1 голос
/ 17 апреля 2020

Вы можете сгладить и объединить все ваши numpy массивы, рассчитать порог с помощью np.percentile и изменить исходные массивы на основе этого порога.

import numpy as np

# Define 3 numpy arrays-
x = np.random.uniform(low = -1000, high = 1000, size = (3, 3, 64))
y = np.random.uniform(low = -1000, high = 1000, size = (3, 3, 128))
z = np.random.uniform(low = -1000, high = 1000, size = (3, 3, 256))

# your list of arrays
arrs = [x, y, z]

# flatten all arrays
flattened = [a.flatten() for a in arrs]
# calculate the thresshold
threshold = np.percentile(abs(np.concatenate(flattened)), 10)

# set values to 0 when smaller than thresshold
for arr in arrs:
    arr[abs(arr) < threshold] = 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...