AttributeError: объект ‘float’ не имеет атрибута ‘isin’ при использовании

#python #pandas #function #if-statement #attributeerror

#python #панды #функция #if-оператор #ошибка атрибута

Вопрос:

У меня есть таблица численности населения в двух странах за разные годы, которая выглядит следующим образом:

 
   year   pop1          pop2
0   0   1.000000e 08    1.000000e 08
1   1   9.620000e 07    9.970000e 07
2   2   9.254440e 07    9.940090e 07
3   3   8.902771e 07    9.910270e 07
4   4   8.564466e 07    9.880539e 07

  

В таблице содержится информация только о первых 300 годах.

Я пытаюсь создать функцию, которая сообщит, в каком году население уменьшилось / увеличилось в 2 раза, в 10 раз и в 100 раз. С помощью jezrael я создал следующую функцию:

 
def find_year(df,init_pop,multiplier):
    pop_size=init_pop*multiplier
    pop1_values=df['pop1'].unique().tolist()
    pop2_values=df['pop2'].unique().tolist()
    
   s=pd.DataFrame(df.set_index('year').sub(pop_size).abs().idxmin(),columns =[multiplier])
   return(s)

  

Проблема в том, что темпы роста различны в каждой популяции, и для этого, если я проверю, когда население уменьшится на 10 или 100, одно из заполнений достигнет этой точки более чем за 300 лет, но в этом случае моя функция не работает и выдает 300 как максимальное значение.

это, например, приводит к тому, что при запуске pop уменьшается на 0,1 и 0,01 (в том же году для pop2, что неверно):

 find_year(data,100000000,0.1)

>>>     0.1
pop1    59
pop2    300



find_year(data,100000000,0.01)

>>>     0.01
pop1    119
pop2    300
  

чтобы исправить это, я создал условия внутри функции, которая проверяет, является ли:

 pop_size=init_pop*multiplier
  

находится внутри одного из столбцов в исходном df, и если нет, он не добавит его к результатам. Я пытался сделать это таким образом:

 def find_year(df,init_pop,multiplier):
    pop_size=init_pop*multiplier
    pop1_values=df['pop1'].unique().tolist()
    pop2_values=df['pop2'].unique().tolist()
    
    if pop_size.isin(pop1_values) amp; pop_size.isin(pop2_values):
        
        s=pd.DataFrame(df.set_index('year').sub(pop_size).abs().idxmin(),columns =[multiplier])
        return(s)
    elif pop_size.isin(pop1_values) amp; ~pop_size.isin(pop2_values):
        s=pd.DataFrame(df.set_index('year').sub(pop_size).abs().idxmin(),columns =[multiplier])
        s.drop('pop2',axis=0,inplace=True)
        return(s)
    elif pop_size.isin(pop2_values) amp; ~pop_size.isin(pop1_values):
        
        s=pd.DataFrame(df.set_index('year').sub(pop_size).abs().idxmin(),columns =[multiplier])
        s.drop('pop1',axis=0,inplace=True)
        return(s)
        
        
  

но когда я запускаю его, я получаю:

AttributeError: объект ‘float’ не имеет атрибута ‘isin’

Я также пытался изменить числа на целое число, но я все равно получил ту же ошибку, только вместо «float» он сказал int. Я не понимаю, почему это происходит.

Моя конечная цель: добавить условие, что если переменная «pop_size» отсутствует в столбцах pop1 или pop2 исходной таблицы, она удалит эту строку (в которой говорится, что на это уходит 300 лет) из результатов df.

редактировать: как создать мои данные:

 def growth(p,r,t):
    time=np.arange(0,t 1,1)
    res=[p]
    for t in time:
        p=p*r
        res.append(p)
    return(pd.DataFrame(list(zip(time, res)),columns =['year','pop']))
        
country1=growth(100000000,0.962,300)
country2=growth(100000000,0.997,300)

data=pd.concat([country1, country2['pop']],axis=1)
data.columns=['year','pop1','pop2']
data

  

Ответ №1:

Вы получаете ошибку, потому int что ни float один из них не имеет isin атрибута. Он определен в фрейме данных pandas. Теперь вот что может решить вашу проблему:

 def find_year(df, init_pop, multiplier):
    pop_size = init_pop*multiplier
    pop1_values = df['pop1'].unique().tolist()
    pop2_values = df['pop2'].unique().tolist()
    s = pd.DataFrame(df.set_index('year').sub(
        pop_size).abs().idxmin(), columns=[multiplier])

    if pop_size in pop1_values and not pop_size in pop2_values:
        s.drop('pop2', axis=0, inplace=True)
    elif pop_size in pop2_values and not pop_size in pop1_values:
        s.drop('pop1', axis=0, inplace=True)

    return s
  

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

1. это вызывает ошибку AttributeError: объект ‘list’ не имеет атрибута ‘values’

2. @Reut Я не заметил, что вы преобразовали фрейм данных в list Я обновил свой ответ, пожалуйста, проверьте сейчас.

3. @Reut Пожалуйста, дайте мне знать, если есть какие-либо другие ошибки, потому что я не могу протестировать свой код на данных, которые вы пытаетесь.

4. now просто ничего не возвращает. Я отредактировал исходное сообщение с помощью scropt для создания тех же данных, которые я использовал

5. @Reut Я отредактировал свой код, и он работает, но результат остается тем же. Может быть какая-то проблема с вашим логином, или это может быть и мой код. Итак, можете ли вы опубликовать и протестировать варианты или ожидаемый результат?