Маскирование двумерного массива и работа со вторым массивом на основе маскированных индексов - PullRequest
0 голосов
/ 25 мая 2018

У меня есть функция, которая читает и выводит двумерный массив.Я хочу, чтобы выходные данные были постоянными (в данном случае пи) для каждого индекса на входе, равного 0, в противном случае я выполняю некоторые математические вычисления.Например:

import numpy as np
import numpy.ma as ma

def my_func(x):

    mask = ma.where(x==0,x)

    # make an array of pi's the same size and shape as the input
    y = np.pi * np.ones(x)

    # psuedo-code bit I can't figure out
    y.not_masked = y**2

    return y 

my_array = [[0,1,2],[1,0,2],[1,2,0]]

result_array = my_func(my_array)

Это должно дать мне следующее:

result_array = [[3.14, 1, 4],[1, 3.14, 4], [1, 4, 3.14]]

Т.е. он применил y**2 к каждому элементу в 2D-списке, который не равен нулю, и замененвсе нули с пи.

Мне это нужно, потому что моя функция будет включать в себя деление, а я заранее не знаю индексов.Я пытаюсь преобразовать учебник по Matlab из учебника в Python, и эта функция вводит меня в заблуждение!

Спасибо

Ответы [ 3 ]

0 голосов
/ 25 мая 2018

Я бы посоветовал вместо использования масок использовать логический массив для достижения желаемого.

def my_func(x):
    #create a boolean matrix, a, that has True where x==0 and
    #False where x!=0 

    a=x==0

    x[a]=np.pi

    #Use np.invert to flip where a is True and False so we can 
    #operate on the non-zero values of the array

    x[~a]=x[~a]**2

    return x #return the transformed array

my_array = np.array([[0.,1.,2.],[1.,0.,2.],[1.,2.,0.]])

result_array = my_func(my_array)

это дает вывод:

array([[ 3.14159265,  1.        ,  4.        ],
       [ 1.        ,  3.14159265,  4.        ],
       [ 1.        ,  4.        ,  3.14159265]])

Обратите внимание, что я специально передал функции пустой массив, изначально вы передали список, и это вызовет проблемы при попытке сделатьматематические операции.Также обратите внимание, что я определил массив с 1, а не с 1, чтобы убедиться, что это был массив с плавающей точкой, а не целые числа, потому что, если это массив целых чисел, когда вы устанавливаете значения, равные pi, он усекается до 3.

Возможно, было бы неплохо добавить кусок в функцию, чтобы проверить dtype входного аргумента и посмотреть, является ли он пустым массивом, а не списком или другим объектом, а также убедиться, что он содержит числа с плавающей запятой.и, если нет, вы можете настроить соответственно.

РЕДАКТИРОВАТЬ: перейти на использование ~ а, а не инвертировать (а) в соответствии с предложением Скотти1.

0 голосов
/ 25 мая 2018

Просто используйте np.where() напрямую:

y = np.where(x, x**2, np.pi)

Пример:

>>> x = np.asarray([[0,1,2],[1,0,2],[1,2,0]])
>>> y = np.where(x, x**2, np.pi)
>>> print(y)
[[ 3.14159265  1.          4.        ]
 [ 1.          3.14159265  4.        ]
 [ 1.          4.          3.14159265]]
0 голосов
/ 25 мая 2018

Попробуйте это:

my_array = np.array([[0,1,2],[1,0,2],[1,2,0]]).astype(float)

def my_func(x):

    mask = x == 0

    x[mask] = np.pi
    x[~mask] = x[~mask]**2  # or some other operation on x...

    return x
...