Поднять элементы массива до ряда экспонент - PullRequest
0 голосов
/ 26 сентября 2019

Предположим, у меня есть простой массив, такой как:

a = np.arange(9)
>> array([0, 1, 2, 3, 4, 5, 6, 7, 8])

Если я хочу поднять каждый элемент до следующих двух степеней, я могу сделать это следующим образом:

power_2 = np.power(a,2)
power_4 = np.power(a,4)

Затем я могу объединить массивы следующим образом:

np.c_[power_2,power_4]
>> array([[   0,    0],
       [   1,    1],
       [   4,   16],
       [   9,   81],
       [  16,  256],
       [  25,  625],
       [  36, 1296],
       [  49, 2401],
       [  64, 4096]])

Какой эффективный способ сделать это, если я заранее не знаю степень четного монома (наибольшее кратное 2)?

Ответы [ 3 ]

1 голос
/ 26 сентября 2019

Следует отметить, что x ^ (2 ^ n) = (... ((((x ^ 2) ^ 2) ^ 2) ... ^ 2) означает, что вы можете вычислять каждый столбец из предыдущеговзяв квадрат.

Если вы заранее знаете количество столбцов, вы можете сделать что-то вроде:

import functools as ft

a = np.arange(5)
n = 4

out = np.empty((*a.shape,n),a.dtype)
out[:,0] = a

# Note: this works by side-effect!
# The optional second argument of np.square is "out", i.e. an
# array to write the result to (nonetheless the result is also
# returned directly)
ft.reduce(np.square,out.T)

out
# array([[    0,     0,     0,     0],
#        [    1,     1,     1,     1],
#        [    2,     4,    16,   256],
#        [    3,     9,    81,  6561],
#        [    4,    16,   256, 65536]])

Если количество столбцов заранее не известно, тогда самый эффективный методсостоит в создании списка столбцов, добавлении по мере необходимости и только в конце использования np.column_stack или np.c_ (при использовании np.c_ не забудьте сначала привести список к кортежу).

0 голосов
/ 26 сентября 2019

Самый элегантный способ, который я мог придумать, - это не вычислять показатели заранее.Поскольку ваши экспоненты следуют очень простому шаблону, вы можете выразить все, используя списки.

result = [item**2*index for index,item in enumerate(a)]

Если вы работаете с довольно большими наборами данных, это приведет к серьезным накладным расходам.Этот оператор немедленно выполнит все вычисления и сохранит все вычисленные элементы в одном большом массиве.Чтобы смягчить эту проблему, вы можете воспользоваться генератором выражений, которые будут генерировать данные на лету.

result = (item**2*index for index,item in enumerate(a))

Подробнее см. здесь .

0 голосов
/ 26 сентября 2019

Простой подход:

exponents = [2**n for n in a]
[a**e for e in exponents]

Это отлично работает для сравнительно небольших чисел, но я вижу, как выглядит числовое переполнение для больших чисел.(Хотя я могу прекрасно вычислить эти высокие мощности, используя скаляры.)

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