perimosocordiae
perimosocordiae

Reputation: 17797

Inverse of numpy's bincount function

Given an array of integer counts c, how can I transform that into an array of integers inds such that np.all(np.bincount(inds) == c) is true?

For example:

>>> c = np.array([1,3,2,2])
>>> inverse_bincount(c)  # <-- what I need

array([0,1,1,1,2,2,3,3])

Context: I'm trying to keep track of the location of multiple sets of data, while performing computation on all of them at once. I concatenate all the data together for batch processing, but I need an index array to extract the results back out.

Current workaround:

def inverse_bincount(c):
  return np.array(list(chain.from_iterable([i]*n for i,n in enumerate(c))))

Upvotes: 5

Views: 1345

Answers (3)

Eelco Hoogendoorn
Eelco Hoogendoorn

Reputation: 10759

The following is about twice as fast on my machine than the currently accepted answer; although I must say I am surprised by how well np.repeat does. I would expect it to suffer a lot from temporary object creation, but it does pretty well.

import numpy as np
c = np.array([1,3,2,2])
p = np.cumsum(c)
i = np.zeros(p[-1],np.int)
np.add.at(i, p[:-1], 1)
print np.cumsum(i)

Upvotes: 1

njzk2
njzk2

Reputation: 39406

no numpy needed :

c = [1,3,2,2]
reduce(lambda x,y: x + [y] * c[y], range(len(c)), [])

Upvotes: 1

Kiwi
Kiwi

Reputation: 2816

using numpy.repeat :

np.repeat(np.arange(c.size), c)

Upvotes: 13

Related Questions