Как избавиться от раздражающего предупреждения, когда я использую метод удаления фрейма данных Pandas с условием?

#python #pandas #dataframe #data-science

#python #pandas #фрейм данных #наука о данных

Вопрос:

Я запускаю этот код:

 from datetime import datetime

df_students_ages = df_students.dropna()
df_students_ages.loc[:, ['birth_year']] = df_students_ages.birthday.apply(lambda x : x.split('-')[0])

#conditional drop
df_students_ages.drop(df_students_ages[df_students_ages.birth_year > '2015'].index, inplace=True)
df_students_ages.drop(df_students_ages[df_students_ages.birth_year < '1920'].index, inplace=True)

df_students_ages.drop(columns='birth_year', inplace=True)
df_students_ages.loc[:, ['birthday']] = df_students_ages.birthday.apply(pd.to_datetime)

def from_dob_to_age(born):
    today = pd.to_datetime(datetime.now().date())
    return today.year - born.year - ((today.month, today.day) < (born.month, born.day))

df_students_ages.loc[:, ['age']] = df_students_ages.birthday.apply(lambda x: from_dob_to_age(x))

df_students_ages.sort_values('age')
 

Я получаю это предупреждение:

 ~/opt/anaconda3/lib/python3.8/site-packages/pandas/core/indexing.py:659: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  self.obj[k] = np.nan
~/opt/anaconda3/lib/python3.8/site-packages/pandas/core/indexing.py:1745: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  isetter(ilocs[0], value)
~/opt/anaconda3/lib/python3.8/site-packages/pandas/core/frame.py:4163: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  return super().drop(
 

Как избежать его получения? Что еще я должен поместить в форму ‘.loc[]’? Я понятия не имею, как объединить его с условным удалением.

Результат аккуратный.

Результат аккуратный

Ответ №1:

в

 #conditional drop
df_students_ages.drop(df_students_ages[df_students_ages.birth_year > '2015'].index, inplace=True)
df_students_ages.drop(df_students_ages[df_students_ages.birth_year < '1920'].index, inplace=True)

df_students_ages.drop(columns='birth_year', inplace=True)
df_students_ages.loc[:, ['birthday']] = df_students_ages.birthday.apply(pd.to_datetime)
 

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

 #conditional drop
df_students_ages = df_students_ages.drop(df_students_ages[df_students_ages.birth_year > '2015'].index, inplace=True)
df_students_ages = df_students_ages.drop(df_students_ages[df_students_ages.birth_year < '1920'].index, inplace=True)

df_students_ages = df_students_ages.drop(columns='birth_year', inplace=True)
df_students_ages = df_students_ages.loc[:, ['birthday']] = df_students_ages.birthday.apply(pd.to_datetime)
 

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

1. inplace=True флаг используется вместо уравнения

2. Спасибо за ваш комментарий, если мы используем предложенные строки без ‘inplace = True`, будут ли это выдавать те же раздражающие сообщения?

3. Спасибо за идею, она действительно удалила часть моих предупреждений, вот это: « {…} SettingWithCopyWarning: значение пытается быть установлено для копии фрагмента из фрейма данных См. Предостережения в документации: {…} return super().drop( « Вышеуказанные предупреждения остаются.

4. какие сообщения остались (все еще существовали)?

5. Копировать код в комментариях неудобно.

Ответ №2:

Я сам нашел ответ. Единственное, что мне действительно нужно сделать, это скопировать весь исходный фрейм данных, прежде чем начинать удалять недопустимые строки. Таким образом, я даже избегал использования функции ‘.loc[]’ там, где мог. Окончательный код выглядит следующим образом:

 from datetime import datetime

# this is what has actually changed
df_students_ages = df_students
df_students_ages.dropna(inplace=True)

# new column creation without .loc
df_students_ages['birth_year'] = df_students_ages.birthday.apply(lambda x : x.split('-')[0])
# dropping inplace
df_students_ages.drop(df_students_ages[df_students_ages.birth_year > '2015'].index, inplace=True)
df_students_ages.drop(df_students_ages[df_students_ages.birth_year < '1920'].index, inplace=True)

df_students_ages = df_students_ages.drop(columns='birth_year')
df_students_ages.birthday = df_students_ages.birthday.apply(pd.to_datetime)

def from_dob_to_age(born):
    today = pd.to_datetime(datetime.now().date())
    return today.year - born.year - ((today.month, today.day) < (born.month, born.day))

# new column creation without .loc 
df_students_ages['age'] = df_students_ages.birthday.apply(lambda x: from_dob_to_age(x))

df_students_ages.sort_values('age')