Применение различных функций к массиву в зависимости от значения - PullRequest
0 голосов
/ 09 мая 2018

Я пытаюсь применить другую функцию к первой и второй части массива numpy.Таким образом, в этом примере, умножение слагаемых меньше 0,5 на 2 и добавление 1 к срокам 0,5 и выше.

def myFunc:
    x = numpy.linspace(0,1,11)
    def test():
        for i in x:
            if i < 0.5:
                a = i*2
            else:
                a = i+1.0
        return(a)

print(test())

Который я хочу вернуть:

[0,0.2,0.4,0.6,0.8,1.5,1.6,1.7,1.8,1.9,2]

Спасибо.

Ответы [ 5 ]

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

Если вы хотите numpy решение, я буду использовать select

np.select([x<0.5,x>=0.5],[x*2,x+1])
Out[905]: array([0. , 0.2, 0.4, 0.6, 0.8, 1.5, 1.6, 1.7, 1.8, 1.9, 2. ])
0 голосов
/ 09 мая 2018

Понимание списка (ответ @ chrisz) - лучший метод.

Я просто помогу вам с вашим кодом. Это почти правильно, но вам нужно получить доступ к элементу массива вместо локальной переменной a, чтобы он работал. Вы можете перебирать индексы и получать доступ с синтаксисом array[index], как показано ниже:

def myFunc(x):
    for i in range(len(x)):
        if x[i] < 0.5:
            x[i] *= 2
        else:
            x[i] += 1.0
    return(x)

    print(test())
x = np.linspace(0,1,11)
myFunc(x)

Кроме того, когда вы определяете функцию, вы должны указать, какие параметры ей нужны (т.е. вы должны написать def myFunc(): вместо def myFunc:.

Надеюсь, вы понимаете:)

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

Это должно сделать это:

x[x < 0.5] *= 2
x[x >= 0.5] +=1

Если вы хотите придерживаться numpy, это гораздо предпочтительнее, чем списки.

Вот краткое сравнение с использованием списка и маскировки numpy:

def myFunc_lc(x):
    return np.asarray([i*2 if i < 0.5 else i+1 for i in x])

def myFunc_np(x):
    x[x < 0.5] *= 2
    x[x >= 0.5] +=1
    return x

def myFunc_np2(x):  # using a constant masking array
    ma = x < 0.5
    x[ma] *= 2
    x[~ma] +=1
    return x

x = np.linspace(0, 1, 11)
%timeit myFunc_np(x)  # 6.62 µs ± 160 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit myFunc_np2(x)  # 6.24 µs ± 113 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit myFunc_lc(x)  # 6.75 µs ± 160 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit np.select([x<0.5,x>=0.5],[x*2,x+1])  # 39.9 µs ± 1.78 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

x = np.linspace(0, 1, 10000)
%timeit myFunc_np(x)  # 43.4 µs ± 1.13 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit myFunc_np2(x)  # 43.8 µs ± 1.26 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit myFunc_lc(x)  # 3.7 ms ± 103 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit np.select([x<0.5,x>=0.5],[x*2,x+1])  # 79.2 µs ± 2.54 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

Полагаю, совершенно очевидно, почему маскирование numpy лучше, чем понимание списка. Особенно при использовании больших массивов numpy намного быстрее. Используя маленькие массивы, Numpy работает лишь немного быстрее. np.select действительно медленный для коротких массивов, но вполне подходит для больших массивов. Создание маски в myFunc_np2 еще быстрее для небольших массивов, но немного медленнее для больших массивов.

0 голосов
/ 09 мая 2018
x = np.linspace(0,1,11)
x[x<0.5]*=2
x[x>=0.5]+=1
0 голосов
/ 09 мая 2018

Вы можете просто использовать понимание списка:

[i*2 if i < 0.5 else i+1 for i in x]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...