Hi all, I dont want to run a loop for this but it should be possible using numpy "smart" ways. a = np.ones(30) idx = np.array([2,3,2]) # there is a duplicate index of 2 a += 2
a array([ 1., 1., 3., 3., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
But if we do this : for i in range(idx.shape[0]): a[idx[i]] += 2
a array([ 1., 1., 5., 3., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
How to achieve the second result without looping?? Thanks Santhosh
Sorry typo : a = np.ones(30) idx = np.array([2,3,2]) # there is a duplicate index of 2 a[idx] += 2 On Fri, Feb 22, 2013 at 8:35 PM, santhu kumar <mesanthu@gmail.com> wrote:
Hi all,
I dont want to run a loop for this but it should be possible using numpy "smart" ways.
a = np.ones(30) idx = np.array([2,3,2]) # there is a duplicate index of 2 a += 2
a array([ 1., 1., 3., 3., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
But if we do this : for i in range(idx.shape[0]): a[idx[i]] += 2
a array([ 1., 1., 5., 3., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
How to achieve the second result without looping?? Thanks Santhosh
a = np.ones(30) idx = np.array([2, 3, 2]) a += 2 * np.bincount(idx, minlength=len(a))
a array([ 1., 1., 5., 3., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
As for speed: def loop(a, idx): for i in idx: a[i] += 2 def count(a, idx): a += 2 * np.bincount(idx, minlength=len(a)) %timeit loop(np.ones(30), np.array([2, 3, 2])) 10000 loops, best of 3: 19.9 us per loop %timeit count(np.ones(30), np.array(2, 3, 2])) 100000 loops, best of 3: 19.2 us per loop So no big difference here. But go to larger systems and you'll see a huge difference: %timeit loop(np.ones(10000), np.random.randint(10000, size=100000)) 1 loops, best of 3: 260 ms per loop %timeit count(np.ones(10000), np.random.randint(10000, size=100000)) 100 loops, best of 3: 3.03 ms per loop. ~Brett On Fri, Feb 22, 2013 at 8:38 PM, santhu kumar <mesanthu@gmail.com> wrote:
Sorry typo :
a = np.ones(30) idx = np.array([2,3,2]) # there is a duplicate index of 2 a[idx] += 2
On Fri, Feb 22, 2013 at 8:35 PM, santhu kumar <mesanthu@gmail.com> wrote:
Hi all,
I dont want to run a loop for this but it should be possible using numpy "smart" ways.
a = np.ones(30) idx = np.array([2,3,2]) # there is a duplicate index of 2 a += 2
a array([ 1., 1., 3., 3., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
But if we do this : for i in range(idx.shape[0]): a[idx[i]] += 2
a array([ 1., 1., 5., 3., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
How to achieve the second result without looping?? Thanks Santhosh
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
On Saturday, February 23, 2013 00:45:55 Brett Olsen wrote:
a = np.ones(30) idx = np.array([2, 3, 2]) a += 2 * np.bincount(idx, minlength=len(a))
a
array([ 1., 1., 5., 3., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
Hi! OK, but is there any reason why Santhu's first option doesn't work? Shouldn't it work? Cheers, Ze
On Sat, Feb 23, 2013 at 4:51 PM, Jose Amoreira <ljmamoreira@gmail.com> wrote:
On Saturday, February 23, 2013 00:45:55 Brett Olsen wrote:
a = np.ones(30)
idx = np.array([2, 3, 2])
a += 2 * np.bincount(idx, minlength=len(a))
a
array([ 1., 1., 5., 3., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1.])
Hi!
OK, but is there any reason why Santhu's first option doesn't work? Shouldn't it work?
It can't -- python limitation, unfixable by numpy. The += gets divided into two operations, and there's no way for numpy doing the "+" part to "see" that the two locations you are adding the value to are really "the same" location. There's a pull request to add a new ufunc method to solve this: https://github.com/numpy/numpy/pull/2821 So if/when that gets merged you'll be able to do: np.add.at(a, idx, 2) But it still needs some tweaking and has been stalled for a bit, so might be a good opportunity for someone to take on if they're interested in seeing this functionality... -n
participants (4)
-
Brett Olsen -
Jose Amoreira -
Nathaniel Smith -
santhu kumar