Супер простое назначение столбцов
Фрейм данных 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
по умолчанию индекс имеет нумерацию от 0 до n. И [] =
метод панд пытается быть "умным"
Что на самом деле происходит.
Когда вы используете [] =
метод, pandas спокойно выполняет внешнее соединение или внешнее объединение, используя индекс левого кадра данных и индекс правого ряда.df['column'] = series
Примечание
Это быстро вызывает когнитивный диссонанс, так как []=
метод пытается сделать много разных вещей в зависимости от входных данных, и результат не может быть предсказан, если вы просто не знаете, как работает панда. Поэтому я бы посоветовал не использовать []=
базы кода, но при изучении данных в блокноте это нормально.
Обойти проблему
Если у вас есть pd.Series
и вы хотите, чтобы он был назначен сверху вниз, или если вы кодируете производительный код, и вы не уверены в порядке индекса, стоит того, чтобы его защитить от такого рода проблем.
Вы можете понизить pd.Series
до np.ndarray
или 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
». Но кто знает, как эта функция изменится в будущем, чтобы поддержать новые аргументы. Возможно, имя вашего столбца будет аргументом в новом обновлении панд, что вызовет проблемы с обновлением.