Как сделать так, чтобы эта функция могла использовать массивный массив в качестве аргумента и возвращать массив в python? - PullRequest
1 голос
/ 04 октября 2019

Как сделать так, чтобы эта функция могла использовать массив пустых значений в качестве аргумента и возвращать массив того же размера, в котором tan () применялась поэлементно в python? Мой текущий код показан ниже, но он не возвращает полный массив для обеих опций. Как мне создать выходной массив со значениями tanc ()?

def tanc(x):

    if x == 0:
        return 1
    else:
        return np.tan(x)/x

хочу вывод, такой как: array([ 1.0, 0.27323654e+00, -4.89610183e-17])

Ответы [ 4 ]

2 голосов
/ 04 октября 2019

Вы можете использовать numpy.where и параметр where для np.divide и np.tan.

np.where(cond, a, b) дает массив, где значения из a используются для элементов cond, которые являются правдивыми, и элементы b для ложных элементов cond.

np.divide и * 1021Аргумент * 'where говорит им, что они должны выполнять свою работу только в местах, которые являются истинными в другом массиве, и оставлять некоторые другие элементы неинициализированными (чтобы они могли быть чем угодно, но это не имеет значения, потому что мы не собираемсячтобы использовать их здесь).

nonzero = x != 0 # we only care about places where x isn't 0
# Get tan, then divide by x, but only where x is not 0
nonzero_tan = np.tan(x, where=nonzero)
nonzero_tanc = np.divide(nonzero_tan, x, where=nonzero)
# Where x is not zero, use tan(x)/x, and use 1 everywhere else
tanc = np.where(nonzero, nonzero_tanc, 1)

Как предложено hpaulj в их комментарии, вы можете объединить два последних шага, также используя параметр out в np.divide для определения значений по умолчаниювыходного массива:

nonzero = x != 0
nonzero_tan = np.tan(x, where=nonzero)
tanc = np.divide(nonzero_tan, x, out=np.ones_like(x), where=nonzero)
2 голосов
/ 04 октября 2019

Используйте маску для кодирования вашего состояния для каждого элемента:

mask = (x != 0)

Вы можете применить к множеству операций те части данных, которые удовлетворяют вашему условию:

output = np.zeros(x.shape, dtype=float)
output[~mask] = 1
output[mask] = tan(x[mask]) / x[mask]

Все вместе(с сокращенными избыточными операциями):

def tanc(x):
    output = np.zeros(x.shape, dtype=float)
    output[~mask] = 1
    selected = x[mask]
    output[mask] = tan(selected) / selected
    return output

Post Scriptum

Отличный ответ @ jirasaimok , на мой взгляд, более элегантный (numpythonic, если хотите) способ сделать то же самое: избегать более одного вычисления на элемент и избегать деления на ноль. Я хотел бы предложить, чтобы их ответ был еще более улучшен при использовании ключевого слова out tan и divide, чтобы избежать выделения и копирования ненужных временных массивов:

def tanc(x):
    mask = (x != 0)
    output = np.tan(x, where=mask)
    np.divide(output, x, where=mask, out=output)
    output[~mask] = 1
    return output

Или еще лучше:

def tanc(x):
    mask = (x != 0)
    output = np.tan(x, where=mask, out=np.ones(x.shape, float))
    return np.divide(output, x, where=mask, out=output)
1 голос
/ 04 октября 2019

Вы можете просто сделать:

def tanc(x):
    return np.sinc(x/np.pi)/np.cos(x)
0 голосов
/ 04 октября 2019
def tanc(x):
    if x == 0:
        return 1
    else:
        return np.tan(x)/x

def return_array(some_array):
    return np.array(list(map(tanc, some_array)))
...