Супер простое назначение столбцов
Фреймворк pandas реализован как упорядоченный столбец.
Это означает, что __getitem__
[]
можно использовать не только для получения определенного столбца, но __setitem__
[] =
и для назначения нового столбца.
Например, в этот фрейм данных можно добавить столбец, просто используя метод []
доступа
size name color
0 big rose red
1 small violet blue
2 small tulip red
3 small harebell blue
df['protected'] = ['no', 'no', 'no', 'yes']
size name color protected
0 big rose red no
1 small violet blue no
2 small tulip red no
3 small harebell blue yes
Обратите внимание, что это работает, даже если индекс фрейма данных отключен.
df.index = [3,2,1,0]
df['protected'] = ['no', 'no', 'no', 'yes']
size name color protected
3 big rose red no
2 small violet blue no
1 small tulip red no
0 small harebell blue yes
[] = правильный путь, но будьте осторожны!
Однако, если у вас есть pd.Series
и вы попытаетесь назначить его фреймворку данных, где индексы отключены, вы столкнетесь с проблемами. См. Пример:
df['protected'] = pd.Series(['no', 'no', 'no', 'yes'])
size name color protected
3 big rose red yes
2 small violet blue no
1 small tulip red no
0 small harebell blue no
Это связано с тем, что pd.Series
по умолчанию a имеет индекс, пронумерованный от 0 до n. И [] =
метод pandas пытается быть "умным"
Что на самом деле происходит.
Когда вы используете [] =
метод, pandas незаметно выполняет внешнее соединение или внешнее слияние, используя индекс левого фрейма данных и индекс правого ряда.df['column'] = series
Примечание
Это быстро вызывает когнитивный диссонанс, поскольку []=
метод пытается делать много разных вещей в зависимости от ввода, а результат нельзя предсказать, если вы просто не знаете, как работают панды. Поэтому я бы посоветовал не использовать []=
кодовые базы, но при изучении данных в записной книжке это нормально.
Обойти проблему
Если у вас есть pd.Series
и вы хотите, чтобы он назначался сверху вниз, или если вы кодируете продуктивный код и не уверены в порядке индекса, стоит принять меры для предотвращения такого рода проблем.
Вы можете понизить значение pd.Series
до a np.ndarray
или a list
, это поможет.
df['protected'] = pd.Series(['no', 'no', 'no', 'yes']).values
или
df['protected'] = list(pd.Series(['no', 'no', 'no', 'yes']))
Но это не очень однозначно.
Кто-нибудь из программистов может прийти и сказать: «Эй, это выглядит лишним, я просто оптимизирую это».
Явный способ
Установка индекса в pd.Series
качестве индекса df
является явной.
df['protected'] = pd.Series(['no', 'no', 'no', 'yes'], index=df.index)
Или, что более реалистично, у вас, вероятно, pd.Series
уже есть файл.
protected_series = pd.Series(['no', 'no', 'no', 'yes'])
protected_series.index = df.index
3 no
2 no
1 no
0 yes
Теперь можно назначить
df['protected'] = protected_series
size name color protected
3 big rose red no
2 small violet blue no
1 small tulip red no
0 small harebell blue yes
Альтернативный способ с df.reset_index()
Поскольку проблема заключается в диссонансе индекса, если вы чувствуете, что индекс фрейма данных не должен диктовать что-либо, вы можете просто отбросить индекс, это должно быть быстрее, но это не очень чисто, поскольку ваша функция теперь, вероятно, выполняет две вещи.
df.reset_index(drop=True)
protected_series.reset_index(drop=True)
df['protected'] = protected_series
size name color protected
0 big rose red no
1 small violet blue no
2 small tulip red no
3 small harebell blue yes
Обратите внимание на df.assign
Хотя df.assign
проясните, что вы делаете, на самом деле у него есть те же проблемы, что и выше.[]=
df.assign(protected=pd.Series(['no', 'no', 'no', 'yes']))
size name color protected
3 big rose red yes
2 small violet blue no
1 small tulip red no
0 small harebell blue no
Только следите за тем, df.assign
чтобы ваша колонка не вызывалась self
. Это вызовет ошибки. Это вызывает df.assign
неприятный запах , поскольку в функции есть такие артефакты.
df.assign(self=pd.Series(['no', 'no', 'no', 'yes'])
TypeError: assign() got multiple values for keyword argument 'self'
Вы можете сказать: «Ну, тогда я просто не буду использовать self
». Но кто знает, как эта функция изменится в будущем для поддержки новых аргументов. Возможно, ваше имя столбца будет аргументом в новом обновлении pandas, что вызовет проблемы с обновлением.