Функция Pandas получает ошибку при сравнении плавающего числа и целого числа

#python #pandas #dataframe #function

Вопрос:

Я использую Pandas для анализа набора данных, который включает столбец с именем «Возраст при приеме» (плавающие числа). Я пытался далее классифицировать данные по нескольким небольшим возрастным группам, используя функцию, которую я написал. Тем не менее, я продолжаю получать ошибку «‘<=’ не поддерживается между экземплярами ‘str’ и ‘int’«. Как я могу это исправить, пожалуйста?

Моя функция:

 def convert_age(num):
    
    if num <=7:
        return "0-7 days"
    elif num <= 21:
        return "1-3 weeks"
    elif num <= 42:
        return "3-6 weeks"
    elif num <= 84:
        return "7-12 weeks"
    elif num <= 168:
        return "12 weeks - 6 months"
    elif num <= 365:
        return "6-12 months"
    elif num <= 730:
        return "1-2 years"
    elif num <= 1095:
        return "2-3 years"
    else:
        return "3  years"
   
df['Age on Intake'] = df['Age on Intake'].apply(convert_age)
 

Столбец df [«Возраст при приеме»] содержит плавающие числа:

 0          95.0
1        1096.0
2         111.0
3         111.0
4         397.0
          ...  
21474       NaN
21475       NaN
21476     365.0
21477     699.0
21478      61.0
Name: Age on Intake, Length: 21479, dtype: float64
 

Сообщение об ошибке, которое я получаю:

 ---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-31-ca12621d6b19> in <module>
     22         return "3  years"
     23 
---> 24 df['Age on Intake'] = df['Age on Intake'].apply(convert_age)
     25 
     26 

/opt/anaconda3/lib/python3.8/site-packages/pandas/core/series.py in apply(self, func, convert_dtype, args, **kwds)
   4198             else:
   4199                 values = self.astype(object)._values
-> 4200                 mapped = lib.map_infer(values, f, convert=convert_dtype)
   4201 
   4202         if len(mapped) and isinstance(mapped[0], Series):

pandas/_libs/lib.pyx in pandas._libs.lib.map_infer()

<ipython-input-31-ca12621d6b19> in convert_age(num)
      3 def convert_age(num):
      4 
----> 5     if num <=7:
      6         return "0-7 days"
      7     elif num <= 21:

TypeError: '<=' not supported between instances of 'str' and 'int'
 

Комментарии:

1. Пожалуйста, всегда публикуйте данные и код как код, а не как скриншоты. Также включите образец ваших данных и полную обратную трассировку ошибок.

2. Спасибо @not_speshal за советы. Моя первая публикация и только что отредактированная

3. Хм, это действительно должно сработать, учитывая, что ваша серия показывает dtype: float64 . Однако есть лучшие способы классифицировать эти данные, используя pd.cut . Вы уверены, что уже не .apply(convert_age) обращались к этому столбцу, и это сделало бы его строковыми значениями, а затем вы случайно попытаетесь снова вызвать функцию

4. Я предлагаю вам отладить это, поместив оператор try except в функцию и выведите значение num, если есть ошибка. Затем вы можете найти значение, на котором он не работает.

5. @ALollz Вау, спасибо тебе! Действительно, это произошло потому, что я снова вызвал функцию после того, как изменил код, чтобы добавить еще одну строку оператора «elif». (Борьба нуби). Я действительно ценю вклад каждого!!

Ответ №1:

Похоже, что ваш num аргумент в convert_age получает строку вместо значения int. Попробуйте либо преобразовать его в int, либо игнорировать входящие значения, отличные от int. Подумайте о том, чтобы добавить что-то вроде этого.

 try:
    converted_num = int(num)  # Trying to convert to int.
    # your code goes here
except ValueError:
    # We got an error while converting.
    pass
 

Ответ №2:

Не отвечая напрямую на вопрос (проблема действительно относится к типу проблем, которые можно решить с astype помощью), но вы могли бы выгодно заменить свою недружественную функцию на pandas.cut :

 import numpy as np
import pandas as pd

ages = {0: '0-7 days',
        7: '1-3 weeks',
        21: '3-6 weeks',
        42: '7-12 weeks',
        84: '12 weeks - 6 months',
        168: '6-12 months',
        365: '1-2 years',
        730: '2-3 years',
        1095: '3  years'}

pd.cut(df['Age on Intake'].astype(float),
       bins=list(ages.keys()) [np.inf],
       labels=ages.values(),
      )
 

Комментарии:

1. Очень полезно! Раньше я об этом не знал. Спасибо