Как найти значения float, при этом не учитывая значения NaN

Получил df из файла excel, нужно проверить, что бы в нем не было значений float и str. Могут быть значения только nan и int. Но пустые ячейки в нем имеют <class 'float'>. Таким образом вот эта проверка не срабатывает:

    datatypes = df
    for y in datatypes:
       if datatypes[y].dtype == np.float64:
          print('try')
       else:
          print('false')

Она реагирует на nan и значения float, но nan допустимо! Если так то только пустые значения:

data = df
    for y in data:
        if data[y].isnull().sum():
            print('try')
        else:
            print('false')

Еще раз вопрос, как мне задать условие что бы найти значения float и str, но исключить nan и int ?

Вот df для примера

d = {'col1': [1, 2], 'col2': [3.3, 4.4],'col3': [np.NaN, np.NaN]}
df = pd.DataFrame(data=d)

Ответы (2 шт):

Автор решения: CrazyElf

str определить просто - это dtype == 'object', а для отличения int от float можно заполнить NA нулями, а после этого проверить, что при преобразовании столбца в int значения остаются такими же или нет. Пример:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'data1': [1, np.NaN, 2.2, 2, np.NaN], 
    'data2': [1, 2, np.NaN, 4, 5], 
    'data3': ['1', 2, 3, '4', np.NaN]
    })
for column in df.columns:
    data = df[column].fillna(0)
    print(column, end=': ')
    if df[column].dtype == 'object':
        print('str')
    elif (data.astype(int) == data).all():
        print('int')
    else:
        print('float')

Вывод:

data1: float
data2: int
data3: str

Я проверяю целиком столбцы но если нужно точно так же можно проверять и отдельные ячейки, наверное.

При этом никак невозможно отличить ситуацию, когда в столбце изначально были float числа без дробной части. Столбец из одних int при появлении в нём NA превращается в тип float и такую ситуацию никак нельзя отличить от той, когда в столбце изначально были float без дробной части. С точки зрения Pandas такие столбцы абсолютно одинаковы, мой метод даст оценку, что это был столбец типа int.

→ Ссылка
Автор решения: MaxU

Можно воспользоваться относительно новым типом данных Int64 (обратите внимание на заглавную первую букву):

In [72]: for col in df:
    ...:     try:
    ...:         df[col] = df[col].astype("Int64")
    ...:     except TypeError:
    ...:         pass
    ...:

In [73]: df.dtypes
Out[73]:
data1    float64
data2      Int64
data3     object
dtype: object

Таким образом мы можем преобразовать столбцы, в которых встречаются только целые значения и NaN в тип данных "Int64".

PS в качестве примера данных я использовал пример данных из ответа уважаемого CrazyElf.

→ Ссылка