tumbleweed
tumbleweed

Reputation: 4640

Unhashable type: 'dict' while applying a function with pandas?

I am using requests library to wrap into a function an api:

import pandas as pd
import requests, json

def foo(text):
    payload = {'key': '00ac1ef82687c7533d54be2e9', 'of': 'json', \
               'nko': text, \
               'woei': 'm', \
               'nvn': 'es'}

    r = requests.get('http://api.example.com/foo', params=payload)
    data = json.loads(r.text)
    return data

Then, I would like to apply the above function to the following dataframe:

df:

    colA
0   lore lipsum dolor done
1   lore lipsum
2   done lore
3   dolor lone lipsum

Thus, I tried the following:

df['new_col'] = df['colA'].apply(foo)
df

However, I got the following exception:

/usr/local/lib/python3.5/site-packages/pandas/core/series.py in apply(self, func, convert_dtype, args, **kwds) 2287 2288
if is_extension_type(self.dtype): -> 2289 mapped = self._values.map(f) 2290 else: 2291 values = self.asobject

/usr/local/lib/python3.5/site-packages/pandas/core/categorical.py in map(self, mapper) 950 return self.from_codes(self._codes.copy(), 951 categories=new_categories, --> 952 ordered=self.ordered) 953 except ValueError: 954 return np.take(new_categories, self._codes)

/usr/local/lib/python3.5/site-packages/pandas/core/categorical.py in from_codes(cls, codes, categories, ordered, name) 466 "codes need to be convertible to an arrays of integers") 467 --> 468 categories = cls._validate_categories(categories) 469 470 if len(codes) and (codes.max() >= len(categories) or codes.min() < -1):

/usr/local/lib/python3.5/site-packages/pandas/core/categorical.py in _validate_categories(cls, categories, fastpath) 571 # categories must be unique 572 --> 573 if not categories.is_unique: 574 raise ValueError('Categorical categories must be unique') 575

pandas/src/properties.pyx in pandas.lib.cache_readonly.get (pandas/lib.c:43685)()

/usr/local/lib/python3.5/site-packages/pandas/indexes/base.py in is_unique(self) 1068 def is_unique(self): 1069 """ return if the index has unique values """ -> 1070 return self._engine.is_unique 1071 1072 @property

pandas/index.pyx in pandas.index.IndexEngine.is_unique.get (pandas/index.c:4883)()

pandas/index.pyx in pandas.index.IndexEngine.initialize (pandas/index.c:5828)()

pandas/src/hashtable_class_helper.pxi in pandas.hashtable.PyObjectHashTable.map_locations (pandas/hashtable.c:13788)()

TypeError: unhashable type: 'dict'

Therefore, my question is how can I apply correctly foo function to df column?

Upvotes: 5

Views: 4411

Answers (1)

MaxU - stand with Ukraine
MaxU - stand with Ukraine

Reputation: 210842

Calling df['colA'].apply(foo) is similar to: foo(df['colA']) (where df['colA'] - is a pandas.Series), so your function should be able to accept pandas.Series as an argument - if it's not the case and foo() can accept only scalar arguments, then we have to call foo() for each row:

df[['colA']].apply(foo, axis=1)

NOTE: df[['colA']] - is a DataFrame, as Series.apply() function doesn't have axis argument

Upvotes: 1

Related Questions