Skip to content

Bincount with integer weights should return integer array #6854

Open

Description

@aplavin

Currently it returns array of floats for no reason;

> x = np.arange(10)
> w = np.arange(10)
> np.bincount(a, x)
array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.])

Activity

  1. jaimefrio commented on Dec 18, 2015

    @jaimefrio
    Member

    It is more of a feature than a bug... When present, the weights array is always casted to double before binning. This makes the C code simple, and provides a less surprising experience in case of overflow.

    What exactly is your use case that needs the return to be of integer type? Of what integer type exactly? How would you expect overflow to be handled, if at all?

  2. aplavin commented on Dec 18, 2015

    @aplavin
    Author

    As the user I expect it not to handle overflows at all (like many other operations - e.g. adding two arrays ignores overflows) and return the same type as weights are. Actually I thought it is this way already, but noticed that I can't add the result of bincount to my accumulator array (of int32's) - so I use np.bincount(...).astype(np.int32). Not a big deal of course, but it seems surprising. Another point is that it uses 2x extra memory for int32 or float32 weights, converting them to float64.

    So, if it would greatly complicate the C code, may be it's not worth changing. But as I understand, at least with Cython it shouldn't be any problem at all. Not sure if Cython is widely used in numpy, however.

  3. rgommers commented on Jan 3, 2016

    @rgommers
    Member

    Not sure if Cython is widely used in numpy, however.

    No. It could be used more widely, but currently there's only Cython code in numpy.random.

  4. rgommers commented on Jan 3, 2016

    @rgommers
    Member

    @jaimefrio close this as wontfix then?

  5. perimosocordiae commented on Mar 5, 2016

    @perimosocordiae
    Contributor

    I'm +1 for making bincount work "as expected" regarding the dtype of the weights.

    In my usecase, I need np.bincount([0,0,1], weights=[1j,2j,1j]) to return [3j, 1j], whereas now it raises a TypeError because it tries to convert the complex weights to float. Unfortunately, the hack/fix for this case involves calling bincount twice, handling the real and imaginary sides separately.

    I think it makes sense from an API standpoint to have np.bincount's dtype rules behave the same as np.sum in the presence of weights. After all, they're conceptually doing the same thing.

    I do understand the pain of writing native code that handles lots of dtypes, but I think the benefit outweighs the cost here.

  6. jaimefrio commented on Mar 26, 2016

    @jaimefrio
    Member

    I have just submitted a PR (#7464) addressing this, and have sent a message to the mailing list about the changes. It would be good if you could weigh in the discussion, as I assume there are going to be a number of controversial points to solve before this can be merged.

  7. added a commit that references this issue on Mar 28, 2016
    941baf0
  8. bdice commented on May 19, 2020

    @bdice
    Contributor

    It appears that #7464 has been abandoned. Matching the type of weights seems reasonable to me and I would like to see this feature. @jaimefrio Do you think your PR could be re-opened? Could I help with it?

  9. rossbar commented on May 19, 2020

    @rossbar
    Contributor

    Here's a link to relevant discussion on the mailing list: https://mail.python.org/pipermail/numpy-discussion/2016-March/ (search for "bincount" to get the relevant thread, about halfway down the page).

    The consensus at the time seemed to be for type-promotion behavior consistent with sum FWIW.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions