Tom S
Tom S

Reputation: 631

pandas column calculated using function including dict lookup, 'Series' objects are mutable, thus they cannot be hashed

I am aware there are tons of questions similar to mine, but I could not find the solution to my question in the last 30 Minutes of looking through dozens of threads.

I have a dataframe with hundereds of columns and rows, and use most columns within a function to return a value thats supposed to be added to an additional column.

The problem can be broken down to the following.

lookup = {"foo": 1, "bar": 0}

def lookuptable(input_string, input_factor):
    return lookup[input_string] * input_factor

mydata = pd.DataFrame([["foo", 4], ["bar",3]], columns = ["string","faktor"])
mydata["looked up value"] = lookuptable(mydata["string"], mydata["faktor"])

But this returns:

TypeError: 'Series' objects are mutable, thus they cannot be hashed

Is there a way to avoid this problem without, restructuring the function itself?

Thanks in advance!

Upvotes: 1

Views: 312

Answers (4)

Nk03
Nk03

Reputation: 14949

You can do this without function -

import pandas as pd
lookup = {"foo": 1, "bar": 0}
mydata = pd.DataFrame([["foo", 4], ["bar",3]], columns = ["string","factor"])
mydata["looked up value"] = mydata['string'].map(lookup) * mydata['factor']

Upvotes: 1

Gusti Adli
Gusti Adli

Reputation: 1213

Besides of using .apply(), you can use list comprehension with .iterrows()

mydata["looked up value"] = [lookuptable(row[1]["string"], row[1]["faktor"]) for row in mydata.iterrows()]

Upvotes: 2

Hamza usman ghani
Hamza usman ghani

Reputation: 2243

Try this:

lookup = {"foo": 1, "bar": 0}

def lookuptable(data):
    return lookup[data["string"]] * data["faktor"]

mydata = pd.DataFrame([["foo", 4], ["bar",3]], columns = ["string","faktor"])
mydata["looked up value"] = mydata.apply(lookuptable, axis=1)

print(mydata)

    string  faktor  looked up value
0   foo        4        4
1   bar        3        0

Upvotes: 2

Andreas
Andreas

Reputation: 9197

Your functions accepts 2 parameters, a string and a integer. But you provide 2 pandas series to the function instead. You can iterate through the dataframe however and provide the function with the parameters (row-wise) by using .apply().

mydata["looked up value"] = mydata\
.apply(lambda row: lookuptable(row["string"], row["faktor"]), axis=1)

Upvotes: 1

Related Questions