To filter a DataFrame for numeric values in Pandas we can:
(1) Use str.isnumeric() with boolean indexing
df[df['col'].str.isnumeric()]
(2) Use pd.to_numeric() with errors='coerce'
df[pd.to_numeric(df['col'], errors='coerce').notna()]
(3) Use regular expressions with str.match()
df[df['col'].str.match(r'^\d+$')]
Step 1: Create a DataFrame
Assume we have a DataFrame with a string column that contains both numeric and non-numeric values:
import pandas as pd
data = {
'col': ['123', 'abc', '45', 'xyz', '678', 'hello']
}
df = pd.DataFrame(data)
DataFrame looks like:
| col | |
|---|---|
| 0 | 123 |
| 1 | abc |
| 2 | 45 |
| 3 | xyz |
| 4 | 678 |
| 5 | hello |
Step 2: Why df['col'].filter(str.isnumeric) Fails
The original attempt:
df['col'].filter(str.isnumeric)
does not work because filter() is a DataFrame/Series method that filters labels (index or column names), not values. It expects a function that operates on the index labels, not the cell values. Additionally, str.isnumeric is a string method, not a callable that filter() expects for label-based filtering.
Step 3: Filter Numeric Values with str.isnumeric()
We can use boolean indexing with the string accessor str.isnumeric():
df_numeric = df[df['col'].str.isnumeric()]
result:
| col | |
|---|---|
| 0 | 123 |
| 2 | 45 |
| 4 | 678 |
Step 4: Filter Numeric Values with pd.to_numeric()
Another approach is to attempt conversion and keep only successful conversions:
df_numeric = df[pd.to_numeric(df['col'], errors='coerce').notna()]
result:
| col | |
|---|---|
| 0 | 123 |
| 2 | 45 |
| 4 | 678 |
Step 5: Filter Numeric Values with Regular Expressions
For more control, use str.match() with a regex pattern:
df_numeric = df[df['col'].str.match(r'^\d+$')]
result:
| col | |
|---|---|
| 0 | 123 |
| 2 | 45 |
| 4 | 678 |
Step 6: Convert Filtered Results to Numeric Type
After filtering, you may want to convert the remaining values to integers:
df_numeric['col'] = df_numeric['col'].astype(int)
result:
| col | |
|---|---|
| 0 | 123 |
| 2 | 45 |
| 4 | 678 |
Summary
| Method | Use Case |
|---|---|
str.isnumeric() |
Simple filtering of digit-only strings |
pd.to_numeric() |
Handles mixed types, detects any parseable number |
str.match(r'^\d+$') |
Regex control for custom numeric patterns |
The key mistake in the original code was confusing filter() (a label-based method) with boolean indexing (a value-based approach). For filtering DataFrame values, always use boolean indexing with df[condition].