2015-09-18 4 views
2

Есть ли быстрый способ сделать это;Суммы массивов в массиве

import numpy as np 
a=np.array([1,2,3,4]) 
b=np.array([1,2]) 
c=np.array([a,b]) 
result=magic(c) 

, где magic() это функциональность я хочу, и результат должен быть np.array([10,3]) т.е. numpy.array, содержащие суммы каждого из входных массивов.

+0

Почему бы не 'sums = [sum (arr) для arr in [a, b]]'? –

+0

Являются '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' или ' «' '' Уже создан, или мы можем обойти этот шаг? – askewchan

+0

Ну, я надеялся на отличную реализацию numpy, избегая циклов. @Оливер. W говорит мне, что операции с массивами неравной длины неэффективны в numpy, поэтому, возможно, ответ заключается в том, чтобы думать о другом способе хранения моих данных ... – fen

ответ

1

Из множества возможных решений, это один:

def your_magic(arr): 
    res = np.empty_like(arr) 
    for enu, subarr in enumerate(arr): 
     res[enu] = np.sum(subarr) 
    return res 

Будьте внимательны, хотя, что создание NumPy массив неравных массивов длины не является эффективным на всех и просто очень похож на добавление массивов в обычном Python список. Именно по этой причине возвращаемый массив res в вышеприведенной функции будет в общем случае иметь dtype object.

+0

Спасибо! когда вы говорите неэффективно, мы говорим о памяти/скорости/обоим? – fen

+0

@fen speed: numpy был разработан для вычисления на смежных блоках памяти. Внеся его в принудительный список объектов, вы добавляете ненужное домашнее хозяйство под капот. Посмотрите на [эту тему] (http://stackoverflow.com/q/23795569/2476444), в частности первый комментарий и первое сообщение. @ Комментарий Reut к вашему сообщению - это элегантный способ определить вашу магическую функцию (хотя можно было бы использовать метод numpy 'sum', а не встроенный python). –

2

Вот подборка предложений (ответы и комментарии) и их тайминги:

import numpy as np 

c = np.array([np.random.rand(np.random.randint(1, 300)) for i in range(50)]) 

def oliver(arr): 
    res = np.empty_like(arr) 
    for enu, subarr in enumerate(arr): 
     res[enu] = np.sum(subarr) 
    return res 

def reut(arr): 
    return np.array([a.sum() for a in arr]) 

def hpaulj(arr): 
    d = np.concatenate(arr) 
    l = map(len, arr) 
    i = np.cumsum(l) - l 
    return np.add.reduceat(d, i) 

И их времена:

In [94]: timeit oliver(c) 
1000 loops, best of 3: 457 µs per loop 

In [95]: timeit reut(c) 
1000 loops, best of 3: 317 µs per loop 

In [96]: timeit hpaulj(c) 
10000 loops, best of 3: 94.4 µs per loop 

Это было несколько сложнее реализовать @ hpaulj, но я думаю, что я (и это самый быстрый, если вы используете concatenate вместо hstack)

Смежные вопросы