Python: How to multiply values of a Counter object?
Asked Answered
F

3

8

I'm looking for a way to multiply the values of a Counter object, i.e.

a =  collections.Counter(one=1, two=2, three=3)
>>> Counter({'three': 3, 'two': 2, 'one': 1})

b = a*2
>>> Counter({'three': 6, 'two': 4, 'one': 2})

What's the standard way of doing this in python?

Why I want to do this: I have a sparse feature vector (bag of words represented by a Counter object) that I would like to normalize.

Flashcube answered 15/5, 2014 at 12:17 Comment(2)
Multiply only by 2?Spitter
No, by some real factor. I think you were going to suggest to use +, which would be a solution for my specific case. However, it wouldn't help with my goal of normalizing the vectors (which may have any real length).Flashcube
S
10

You can do this :

for k in a.keys():
     a[k] = a[k] * 2
Saponaceous answered 15/5, 2014 at 12:23 Comment(3)
Thanks! I wasn't aware that this kind of manipulation is possible in python. I actually have been wondering all the time why the docs don't mention any getter/setter functions. Now I know why.Flashcube
You're welcome. You can do the same sort of things with dict.Saponaceous
keys() is not necessarySpitter
D
1

This is an old question, but I just had the same issue during chemical formulae parsing. I extended the Counter class to accept multiplication with integers. For my case, the following is sufficient - it may be extended on demand:

class MCounter(Counter):
    """This is a slight extention of the ``Collections.Counter`` class
    to also allow multiplication with integers."""

    def __mul__(self, other):
        if not isinstance(other, int):
            raise TypeError("Non-int factor")
        return MCounter({k: other * v for k, v in self.items()})

    def __rmul__(self, other):
        return self * other  # call __mul__

    def __add__(self, other):
        return MCounter(super().__add__(other))

So with above, you can multiply from left and right with integers as well. I needed to redefine __add__such that the type MCounter was preserved. If one needs to use subtraction, & and |, that needs to be implemented likewise.

Dessert answered 16/12, 2022 at 23:11 Comment(0)
F
-1

You can add the Counter:

b = a+a
>>> print b
Counter({'three': 6, 'two': 4, 'one': 2})
Fillagree answered 15/5, 2014 at 12:20 Comment(2)
This is the first solution that i encountered but there are two problems: 1) its not feasible for large factors. 2) It only allows multiplication with integers.Flashcube
@JohnSmith, True. You're right. DavidK's method is much more flexible.Fillagree

© 2022 - 2024 — McMap. All rights reserved.