Skip to content

map Method

The map() method applies a function or mapping to each element of a Series. It is useful for element-wise transformations and value substitutions.

Mental Model

map() is a lookup table applied to every element: pass a dict and each value is replaced by its corresponding entry, pass a function and it runs on each element. Unlike apply, map is strictly element-wise and works only on Series. It is the fastest way to do value substitution or simple per-element transforms.

Basic Mapping

Map values using a function.

1. Lambda Function

```python import pandas as pd

df = pd.DataFrame({ 'Age': [25, 30, 35, 40] })

df['Age Group'] = df['Age'].map(lambda x: 'Young' if x < 30 else 'Old') print(df) ```

Age Age Group 0 25 Young 1 30 Old 2 35 Old 3 40 Old

2. Named Function

```python def categorize_age(age): if age < 30: return 'Young' elif age < 50: return 'Middle' else: return 'Senior'

df['Category'] = df['Age'].map(categorize_age) ```

3. Built-in Functions

python df['Name'] = df['Name'].map(str.upper) df['Value'] = df['Value'].map(abs)

Dictionary Mapping

Map values using a dictionary.

1. Value Substitution

```python df = pd.DataFrame({ 'grade': ['A', 'B', 'C', 'A', 'B'] })

grade_points = {'A': 4.0, 'B': 3.0, 'C': 2.0} df['points'] = df['grade'].map(grade_points) print(df) ```

grade points 0 A 4.0 1 B 3.0 2 C 2.0 3 A 4.0 4 B 3.0

2. Missing Keys

```python

Keys not in dictionary become NaN

status_map = {'active': 1, 'inactive': 0} df['status'].map(status_map) # Unknown status → NaN ```

3. Complete Mapping

```python

Provide all possible values

df['status'].map({'active': 1, 'inactive': 0, 'pending': -1}) ```

Series Mapping

Map using another Series.

1. Index-based Mapping

```python mapping_series = pd.Series({ 'A': 'Excellent', 'B': 'Good', 'C': 'Average' })

df['description'] = df['grade'].map(mapping_series) ```

2. From External Data

```python

Map product IDs to names

product_names = products.set_index('id')['name'] orders['product_name'] = orders['product_id'].map(product_names) ```

3. Alignment by Index

The mapping Series is aligned by its index to the values in the source Series.

map vs apply

Understanding when to use each method.

1. map for Series Only

```python

map works on Series, not DataFrame

df['col'].map(func) # OK

df.map(func) # Not available in older pandas

```

2. apply for Both

python df['col'].apply(func) # Series df.apply(func, axis=0) # DataFrame columns df.apply(func, axis=1) # DataFrame rows

3. Performance

```python

map is generally faster for simple mappings

apply is more flexible for complex operations

```

Practical Examples

Common mapping scenarios.

1. Boolean to String

python df['is_active'] = df['is_active'].map({True: 'Yes', False: 'No'})

2. Code to Description

python country_codes = {'US': 'United States', 'UK': 'United Kingdom', 'CA': 'Canada'} df['country_name'] = df['country_code'].map(country_codes)

3. Numeric Binning

```python def bin_value(x): if x < 0: return 'negative' elif x == 0: return 'zero' else: return 'positive'

df['category'] = df['value'].map(bin_value) ```

Handling Missing Results

Deal with unmapped values.

1. fillna After Map

python df['mapped'] = df['col'].map(mapping_dict).fillna('Unknown')

2. Default with get

python df['mapped'] = df['col'].map( lambda x: mapping_dict.get(x, 'Default') )

3. na_action Parameter

```python

Skip NaN values during mapping

df['col'].map(func, na_action='ignore') ```


Exercises

Exercise 1. Create a Series of country codes like ['US', 'UK', 'JP', 'DE']. Use .map() with a dictionary to convert them to full country names (e.g., {'US': 'United States', 'UK': 'United Kingdom', ...}).

Solution to Exercise 1

Map codes to names using a dictionary.

import pandas as pd

codes = pd.Series(['US', 'UK', 'JP', 'DE'])
mapping = {'US': 'United States', 'UK': 'United Kingdom', 'JP': 'Japan', 'DE': 'Germany'}
names = codes.map(mapping)
print(names)

Exercise 2. Create a numeric Series. Use .map() with a lambda to classify each value as 'positive', 'negative', or 'zero'. Compare the result with using .apply() -- both should be identical.

Solution to Exercise 2

Compare map and apply with a lambda.

import pandas as pd

s = pd.Series([-3, 0, 5, -1, 0, 8])
result_map = s.map(lambda x: 'positive' if x > 0 else ('negative' if x < 0 else 'zero'))
result_apply = s.apply(lambda x: 'positive' if x > 0 else ('negative' if x < 0 else 'zero'))
print(result_map)
assert (result_map == result_apply).all()
print("map and apply produce identical results.")

Exercise 3. Create a Series with values that partially match a mapping dictionary (some values have no mapping). Use .map() and observe which values become NaN. Then use .map() followed by .fillna() to provide a default for unmapped values.

Solution to Exercise 3

Handle unmapped values with fillna.

import pandas as pd

s = pd.Series(['a', 'b', 'c', 'd'])
mapping = {'a': 'alpha', 'b': 'beta'}
mapped = s.map(mapping)
print("With NaN:\n", mapped)
filled = mapped.fillna('unknown')
print("With default:\n", filled)