You could use a function like this:

def nan_ints(df, convert_strings=False, subset=None):
    types = ["int64", "float64"]
    if subset is None:
        subset = list(df)
    if convert_strings:
        types.append("object")
    for col in subset:
        if df[col].dtype in types:
            df[col] = (
                df[col].astype(float, errors="ignore").astype("Int64", errors="ignore")
            )
    return df

It iterates through each column and coverts it to an Int64 if it is a int. If it's a float it will convert to a Int64 only if all of the values in the column could be converted to ints other than the NaN's. I've given you the option to convert strings to Int64 as well with the convert_strings argument.

df1 = pd.DataFrame({'a':[1.1,2,3,1],
                  'b':[1,2,3,np.nan],
                  'c':['1','2','3',np.nan],
                  'd':[3,2,1,np.nan]})


nan_ints(df1,convert_strings=True,subset=['b','c'])
df1.info()

Will return the following:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 4 columns):
a    4 non-null float64
b    3 non-null Int64
c    3 non-null Int64
d    3 non-null float64
dtypes: Int64(2), float64(2)
memory usage: 216.0 bytes

if you are going to use this on every DataFrame you could add the function to a module and import it every time you want to use pandas. from my_module import nan_ints Then just use it with something like: nan_ints(pd.read_csv(path))

Note: Nullable integer data type is New in version 0.24.0. Here is the documentation.

Answer from braintho on Stack Overflow
Top answer
1 of 2
5

You could use a function like this:

def nan_ints(df, convert_strings=False, subset=None):
    types = ["int64", "float64"]
    if subset is None:
        subset = list(df)
    if convert_strings:
        types.append("object")
    for col in subset:
        if df[col].dtype in types:
            df[col] = (
                df[col].astype(float, errors="ignore").astype("Int64", errors="ignore")
            )
    return df

It iterates through each column and coverts it to an Int64 if it is a int. If it's a float it will convert to a Int64 only if all of the values in the column could be converted to ints other than the NaN's. I've given you the option to convert strings to Int64 as well with the convert_strings argument.

df1 = pd.DataFrame({'a':[1.1,2,3,1],
                  'b':[1,2,3,np.nan],
                  'c':['1','2','3',np.nan],
                  'd':[3,2,1,np.nan]})


nan_ints(df1,convert_strings=True,subset=['b','c'])
df1.info()

Will return the following:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 4 columns):
a    4 non-null float64
b    3 non-null Int64
c    3 non-null Int64
d    3 non-null float64
dtypes: Int64(2), float64(2)
memory usage: 216.0 bytes

if you are going to use this on every DataFrame you could add the function to a module and import it every time you want to use pandas. from my_module import nan_ints Then just use it with something like: nan_ints(pd.read_csv(path))

Note: Nullable integer data type is New in version 0.24.0. Here is the documentation.

2 of 2
2

I would put my money on monkey patching. The easiest way would be to monkey patch the DataFrame constructor. That should go something like this:

import pandas
pandas.DataFrame.__old__init__ = pandas.DataFrame.__init__
def new_init(self, data=None, index=None, columns=None, dtype=pd.Int64Dtype(), copy=False):
    self.__old__init__(data=data, index=index, columns=None, dtype=dtype, copy=copy)

pandas.DataFrame.__init__ = new_init

Of course, you run the risk of breaking the world. Good luck!

🌐
Pandas
pandas.pydata.org › docs › user_guide › integer_na.html
Nullable integer data type — pandas 3.1.0 documentation
In [3]: pd.array([1, 2, np.nan], dtype="Int64") Out[3]: <IntegerArray> [1, 2, <NA>] Length: 3, dtype: Int64 · All NA-like values are replaced with pandas.NA. In [4]: pd.array([1, 2, np.nan, None, pd.NA], dtype="Int64") Out[4]: <IntegerArray> [1, 2, <NA>, <NA>, <NA>] Length: 5, dtype: Int64 ·
🌐
Practical Business Python
pbpython.com › pandas_dtypes.html
Overview of Pandas Data Types - Practical Business Python
<class 'pandas.core.frame.DataFrame'> RangeIndex: 5 entries, 0 to 4 Data columns (total 10 columns): Customer Number 5 non-null float64 Customer Name 5 non-null object 2016 5 non-null object 2017 5 non-null object Percent Growth 5 non-null object Jan Units 5 non-null object Month 5 non-null int64 Day 5 non-null int64 Year 5 non-null int64 Active 5 non-null object dtypes: float64(1), int64(3), object(6) memory usage: 480.0+ bytes
🌐
GitHub
github.com › pandas-dev › pandas › issues › 27731
Object dtype for int64 and Int64 values in column · Issue #27731 · pandas-dev/pandas · GitHub
August 3, 2019 - [1] has type: <class 'numpy.int64'> [2] has type: <class 'numpy.int64'> [3] has type: <class 'numpy.int64'> [4] has type: <class 'numpy.int64'> [5] has type: <class 'numpy.int64'> [1] has type: <class 'numpy.int64'> [2] has type: <class 'numpy.int64'> [3] has type: <class 'numpy.int64'> [4] has type: <class 'numpy.int64'> [5] has type: <class 'numpy.int64'> df1: Int64 df2: Int64 df3: Int64 · Details INSTALLED VERSIONS ------------------ commit : None python : 3.7.3.final.0 python-bits : 64 OS : Windows OS-release : 10 machine : AMD64 processor : Intel64 Family 6 Model 58 Stepping 9, GenuineIn
🌐
DataCamp
campus.datacamp.com › courses › preprocessing-for-machine-learning-in-python › introduction-to-data-preprocessing
Working with data types | Python
The object type is what pandas ... a mixture of types. int64 and float64 are equivalent to the Python integer and float types, where the 64 refers to the allocation of memory alloted for storing the values, in this case, the number of bits....
🌐
Librarycarpentry
librarycarpentry.github.io › library-python › 03-data-types-and-format
Python for Librarians: Data Types and Formats
August 1, 2018 - If we have a column that contains ... Thus 1.13 would be stored as 1. 1234.345 is stored as 1234. You will often see the data type Int64 in Python which stands for 64 bit integer....
🌐
Data Carpentry
datacarpentry.github.io › python-ecology-lesson › 04-data-types-and-format.html
Data Analysis and Visualization in Python for Ecologists: Data Types and Formats
June 5, 2023 - If we have a column that contains ... be stored as 1. Similarly, 1234.345 would be stored as 1234. You will often see the data type Int64 in pandas which stands for 64 bit integer....
🌐
Pandas
pandas.pydata.org › pandas-docs › stable › user_guide › integer_na.html
Nullable integer data type — pandas 3.0.5 documentation
In [3]: pd.array([1, 2, np.nan], dtype="Int64") Out[3]: <IntegerArray> [1, 2, <NA>] Length: 3, dtype: Int64 · All NA-like values are replaced with pandas.NA.
🌐
Pandas
pandas.pydata.org › docs › reference › arrays.html
pandas arrays, scalars, and data types — pandas 3.1.0 documentation
While individual values in an ... data type, e.g. a PyArrow int64 will be returned as Python int, or NA for missing values. For more information, please see the PyArrow user guide. NumPy cannot natively represent timezone-aware datetimes. pandas supports this with the ...
Find elsewhere
Top answer
1 of 1
1

The question is misleading, because you actually want to know why pandas does this, not python. As for pandas, it tries to find the smallest numerical dtype, as stated in the documentation (downcast): https://pandas.pydata.org/docs/reference/api/pandas.to_numeric.html

downcaststr, default None Can be ‘integer’, ‘signed’, ‘unsigned’, or ‘float’. If not None, and if the data has been successfully cast to a numerical dtype (or if the data was numeric to begin with), downcast that resulting data to the smallest numerical dtype possible according to the following rules:

‘integer’ or ‘signed’: smallest signed int dtype (min.: np.int8)

‘unsigned’: smallest unsigned int dtype (min.: np.uint8)

‘float’: smallest float dtype (min.: np.float32)

As this behaviour is separate from the core conversion to numeric values, any errors raised during the downcasting will be surfaced regardless of the value of the ‘errors’ input.

In addition, downcasting will only occur if the size of the resulting data’s dtype is strictly larger than the dtype it is to be cast to, so if none of the dtypes checked satisfy that specification, no downcasting will be performed on the data.

with code:

import pandas as pd
df = pd.DataFrame(
    {
        'int':[1,2],
        'float':[1.0,2.0],
        'none': [1, None]
     }
)

you might notice that:

print(df.loc[1, 'none'])
# nan

returns nan, not None this is because pandas uses the numpy library. Numpy offers a value which is treated like a number but isn't actually one and is called: not a number (nan), this value is of type float.

import numpy as np
print(type(np.nan))
# <class 'float'>

Since you used None, pandas tries to find the correct data type, finds numbers with missing values, since it can't handle that it casts it to float where it is able to inser np.nan for the missing values.

🌐
Medium
medium.com › @mohamedmostafa9557 › the-possible-data-types-you-can-use-for-series-in-pandas-9a67b27934a1
The possible data types you can use for Series in Pandas | by Mohamed Mostafa | Medium
July 30, 2024 - # Using int64 (no support for NA) df = pd.DataFrame({'a': [1, 2, 3, np.nan]}, dtype='int64') # This will raise an error # Using Int64 (with support for NA) df = pd.DataFrame({'a': [1, 2, 3, pd.NA]}, dtype='Int64') ```
🌐
CodeSignal
codesignal.com › learn › courses › cleaning-and-transforming-data-with-pandas › lessons › data-type-conversion-in-pandas
Data Type Conversion in Pandas | CodeSignal Learn
They provide a larger range and higher precision, with int64 capable of storing values from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807, and float64 offering precision up to about 15 decimal digits.
🌐
Pandas
pandas.pydata.org › docs › reference › api › pandas.api.types.is_int64_dtype.html
pandas.api.types.is_int64_dtype — pandas 3.0.6 documentation
pandas.api.types.is_int64_dtype(arr_or_dtype)[source]# Check whether the provided array or dtype is of the int64 dtype. Deprecated since version 2.1.0: is_int64_dtype is deprecated and will be removed in a future version. Use dtype == np.int64 instead. Parameters: arr_or_dtypearray-like or dtype ·
🌐
Pandas
pandas.pydata.org › docs › reference › api › pandas.Int64Dtype.html
pandas.Int64Dtype — pandas 3.1.0 documentation - PyData |
An ExtensionDtype for int64 integer data. Uses pandas.NA as its missing value, rather than numpy.nan.
🌐
GeeksforGeeks
geeksforgeeks.org › pandas › how-to-convert-float64-columns-to-int64-in-pandas
How to Convert float64 Columns to int64 in Pandas? - GeeksforGeeks
July 23, 2025 - To transform a Pandas column to an integer type within a DataFrame, you have the option to utilize either the DataFrame's astype(int) or the apply() method. This enables the conversion of a column from various data types such as float or string to an integer type, specifically int64 or int32.
🌐
Stack Overflow
stackoverflow.com › questions › 55479542 › int64-usage-difference-between-pandas-array-and-series-pandas-version-0-24
numpy - Int64 usage: difference between pandas array and Series (Pandas version 0.24) - Stack Overflow
In Pandas 0.24, it is possible to assign missing values to integer variables without promoting them to floats. This is done by using dtype "Int64", which is shorthand for Int64Dtype() in the functions that create series.
🌐
X
x.com › ammaryh92 › status › 1489610400157122561
Ammar Yasser on X: "🐼Pandas Tip The difference between Int64 (capital) and int64 (small) data types In a nutshell, the int64 data type does not support null values (NaN, none, <NA>, etc). If we tried to create a series of integers and null values, pandas will change the data type to float64." / X
February 4, 2022 - 🐼Pandas Tip The difference between Int64 (capital) and int64 (small) data types In a nutshell, the int64 data type does not support null values (NaN, none, , etc). If we tried to create a series of integers and null values, pandas will change ...
🌐
Stack Overflow
stackoverflow.com › questions › 60402929 › pandas-read-csv-dtype-definitions-int-int64-int64
dataframe - pandas read_csv dtype definitions : int, int64, 'Int64' - Stack Overflow
Can someone point me in the good direction to understand the (seeming) inconsistency in the way to define dtype during pandas.read_csv ? dtype = int # --> produces error if blank values dtype = int32, int64, and Int64 # --> are not defined dtype = 'Int64' # --> correctly reads csv file as ints and with blank values