pandas TypeError: unhashable type: 'Series' / 'numpy.ndarray' (tested)
TypeError: unhashable type: 'Series' (on Python 3.14: cannot use 'pandas.Series' as a dict key) means a whole column was used as a dict key or set element where one value was expected. The same goes for 'numpy.ndarray'. Tested on Python 3.11 and 3.14 with pandas 2.3.3 and 3.1.0.
1. The error on three setups
import pandas as pd
df = pd.DataFrame({"k": ["a", "b"], "v": [1, 2]})
lookup = {"a": 10, "b": 20}
try:
lookup[df["k"]] # a whole column as a dict key
except TypeError as e:
print("TypeError:", e)
try:
set([df["v"].values]) # a numpy array as a set/dict key
except TypeError as e:
print("TypeError:", e)
Python 3.11, pandas 2.3.3:
TypeError: unhashable type: 'Series'
TypeError: unhashable type: 'numpy.ndarray'
Python 3.14, pandas 2.3.3:
TypeError: cannot use 'pandas.core.series.Series' as a dict key (unhashable type: 'Series')
TypeError: cannot use 'numpy.ndarray' as a set element (unhashable type: 'numpy.ndarray')
Python 3.14, pandas 3.1.0:
TypeError: cannot use 'pandas.Series' as a dict key (unhashable type: 'Series')
TypeError: cannot use 'numpy.ndarray' as a set element (unhashable type: 'numpy.ndarray')
Dict keys and set elements must be hashable, and a Series or NumPy array is a mutable container of many values, so it is not. Python 3.14 adds the "cannot use ... as a dict key" prefix; pandas 3 shortens the class name to pandas.Series. The cause is the same everywhere: a whole column was used where a single value was expected. This often happens inside apply with the wrong axis, or after df["k"] where df.loc[i, "k"] was meant.
2. Fixes
import pandas as pd
df = pd.DataFrame({"k": ["a", "b"], "v": [1, 2]})
lookup = {"a": 10, "b": 20}
print(df["k"].map(lookup).tolist()) # look up each value
print(lookup[df["k"].iloc[0]]) # or one value
print(set(df["v"].tolist())) # plain Python values are hashable
print(df.groupby("k")["v"].sum().to_dict()) # group by column name
Output (identical on pandas 2.3.3 and 3.1.0):
[10, 20]
10
{1, 2}
{'a': 1, 'b': 2}
To look up every value of a column in a dict, use Series.map(dict) (missing keys become NaN). For one value, select it first with .iloc[i] or .loc[label, col]. To put the values in a set or use them as dict keys, convert with .tolist(). In groupby, pass column names rather than arrays when you can.
Related: unhashable type: 'list' · unhashable type: 'dict' · pandas KeyError but the column exists.
Frequently asked questions
Why is a pandas Series unhashable?
It is a mutable container of many values, so Python cannot use it as a dict key or set element. Use one value (.iloc[i]) or convert with .tolist().
How do I look up each value of a column in a dict?
df['col'].map(my_dict). Values missing from the dict become NaN.
What about unhashable type: 'numpy.ndarray'?
Same cause with a NumPy array, often from .values. Convert to a list with .tolist(), or to a tuple if it must be one key.
Written with AI assistance. Measured on 2026-10-23 in Docker: python:3.11-alpine with pandas 2.3.3, and python:3-alpine (Python 3.14) with pandas 2.3.3 and 3.1.0. Each block was run verbatim and the output pasted unedited. PlainHeaders is our extension; Python and pandas are free.