#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')