#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 Я отредактировал свой код, и он работает, но результат остается тем же. Может быть какая-то проблема с вашим логином, или это может быть и мой код. Итак, можете ли вы опубликовать и протестировать варианты или ожидаемый результат?