Introduction
Finding numeric columns in a pandas DataFrame is essential for data preprocessing, statistical analysis, and machine learning pipelines. The primary method is df.select_dtypes(include='number'), which returns a DataFrame containing only numeric columns (int, float, complex). For just the column names, use df.select_dtypes(include='number').columns. Other approaches include pd.api.types.is_numeric_dtype() for checking individual columns and df.describe() which only summarizes numeric columns by default.
Method 1: select_dtypes (Recommended)
1import pandas as pd
2import numpy as np
3
4df = pd.DataFrame({
5 'name': ['Alice', 'Bob', 'Charlie'],
6 'age': [25, 30, 35],
7 'salary': [50000.0, 60000.0, 70000.0],
8 'department': ['Engineering', 'Marketing', 'Sales'],
9 'active': [True, False, True],
10 'score': [88, 92, 85]
11})
12
13# Select only numeric columns
14numeric_df = df.select_dtypes(include='number')
15print(numeric_df)
16# age salary score
17# 0 25 50000.0 88
18# 1 30 60000.0 92
19# 2 35 70000.0 85
20
21# Get just the column names
22numeric_cols = df.select_dtypes(include='number').columns.tolist()
23print(numeric_cols)
24# ['age', 'salary', 'score']
Include and Exclude Options
1# Include only integers
2int_cols = df.select_dtypes(include='int64')
3print(int_cols.columns.tolist()) # ['age', 'score']
4
5# Include only floats
6float_cols = df.select_dtypes(include='float64')
7print(float_cols.columns.tolist()) # ['salary']
8
9# Include multiple types
10num_cols = df.select_dtypes(include=['int64', 'float64'])
11
12# Include all numeric types with np.number
13num_cols = df.select_dtypes(include=[np.number])
14
15# Exclude numeric columns (get non-numeric)
16non_numeric = df.select_dtypes(exclude='number')
17print(non_numeric.columns.tolist())
18# ['name', 'department', 'active']
Method 2: pd.api.types.is_numeric_dtype
Check individual columns:
1from pandas.api.types import is_numeric_dtype
2
3for col in df.columns:
4 print(f"{col}: {is_numeric_dtype(df[col])}")
5# name: False
6# age: True
7# salary: True
8# department: False
9# active: True (booleans are considered numeric!)
10# score: True
1# Get numeric column names using a list comprehension
2numeric_cols = [col for col in df.columns if is_numeric_dtype(df[col])]
3print(numeric_cols)
4# ['age', 'salary', 'active', 'score']
Note: is_numeric_dtype considers boolean columns as numeric. Use select_dtypes(include='number') if you want to exclude booleans.
Method 3: df.dtypes Inspection
1print(df.dtypes)
2# name object
3# age int64
4# salary float64
5# department object
6# active bool
7# score int64
8
9# Filter by dtype kind
10numeric_cols = df.dtypes[df.dtypes.apply(lambda x: x.kind in 'iufcb')].index.tolist()
11# i = integer, u = unsigned int, f = float, c = complex, b = boolean
dtype kind codes:
Boolean Handling
Booleans are a common source of confusion:
1# select_dtypes with 'number' EXCLUDES booleans
2df.select_dtypes(include='number').columns.tolist()
3# ['age', 'salary', 'score'] — no 'active'
4
5# select_dtypes with np.number EXCLUDES booleans
6df.select_dtypes(include=[np.number]).columns.tolist()
7# ['age', 'salary', 'score']
8
9# is_numeric_dtype INCLUDES booleans
10is_numeric_dtype(df['active']) # True
11
12# To include booleans explicitly:
13df.select_dtypes(include=['number', 'bool']).columns.tolist()
14# ['age', 'salary', 'active', 'score']
Practical Use Cases
Correlation Matrix
1# Compute correlation only for numeric columns
2numeric_df = df.select_dtypes(include='number')
3correlation = numeric_df.corr()
4print(correlation)
Scaling/Normalization
1from sklearn.preprocessing import StandardScaler
2
3numeric_cols = df.select_dtypes(include='number').columns
4
5scaler = StandardScaler()
6df[numeric_cols] = scaler.fit_transform(df[numeric_cols])
Fill Missing Values
1# Fill numeric columns with median, non-numeric with mode
2numeric_cols = df.select_dtypes(include='number').columns
3non_numeric_cols = df.select_dtypes(exclude='number').columns
4
5df[numeric_cols] = df[numeric_cols].fillna(df[numeric_cols].median())
6df[non_numeric_cols] = df[non_numeric_cols].fillna(df[non_numeric_cols].mode().iloc[0])
Summary Statistics
1# describe() shows only numeric columns by default
2print(df.describe())
3
4# Include all columns
5print(df.describe(include='all'))
6
7# Include only specific types
8print(df.describe(include=[np.number]))
Handling Mixed-Type Columns
1# Columns with mixed types are stored as 'object'
2df_messy = pd.DataFrame({
3 'value': ['100', '200', 'N/A', '400'], # Object dtype
4 'count': [1, 2, 3, 4] # Int dtype
5})
6
7# 'value' is not numeric even though it contains number-like strings
8print(df_messy.select_dtypes(include='number').columns.tolist())
9# ['count']
10
11# Convert to numeric where possible
12df_messy['value'] = pd.to_numeric(df_messy['value'], errors='coerce')
13print(df_messy.dtypes)
14# value float64 (N/A becomes NaN)
15# count int64
Common Pitfalls
Assuming boolean columns are excluded by is_numeric_dtype: is_numeric_dtype(bool_series) returns True. Use select_dtypes(include='number') which excludes booleans, or explicitly check dtype.kind != 'b'.
Not converting string-encoded numbers: Columns read from CSV files may contain numbers stored as strings (object dtype). Use pd.to_numeric(col, errors='coerce') to convert them before selecting numeric columns.
Using df.dtypes == 'int64' for exact matching: This misses int32, float64, and other numeric types. Use select_dtypes(include='number') to catch all numeric types regardless of bit width.
Modifying a view instead of a copy: df.select_dtypes(include='number') returns a new DataFrame. Modifying it does not change the original. Use df[numeric_cols] to modify specific columns in the original DataFrame.
Ignoring nullable integer types: Pandas nullable types (Int64, Float64 with capital letters) may not be selected by include='number' in older pandas versions. Use include=[np.number, 'Int64', 'Float64'] or upgrade to pandas 2.0+ where they are handled correctly.
Summary
Use df.select_dtypes(include='number') to get a DataFrame of all numeric columns
Use .columns.tolist() to get just the column names as a list
select_dtypes(include='number') excludes booleans; is_numeric_dtype includes them
Use pd.to_numeric(col, errors='coerce') to convert string columns to numeric before analysis
Practical applications include correlation matrices, scaling, missing value imputation, and train/test splits