Я б очікував, що і ваш синтаксис також спрацює. Проблема виникає через те, що при створенні нових стовпців із синтаксисом списку стовпців ( df[[new1, new2]] = ...
), панди вимагають, щоб права сторона була DataFrame (зауважте, що це насправді не має значення, якщо стовпці DataFrame мають ті ж назви, що і стовпці ви створюєте).
Ваш синтаксис прекрасно працює для призначення скалярних значень існуючим стовпцям, а панди також раді призначити скалярні значення новому стовпчику, використовуючи синтаксис "один стовпець" ( df[new1] = ...
). Таким чином, рішення полягає в тому, щоб перетворити це на кілька одноколонних призначень або створити відповідний DataFrame для правої частини.
Ось кілька підходів, які будуть працювати:
import pandas as pd
import numpy as np
df = pd.DataFrame({
'col_1': [0, 1, 2, 3],
'col_2': [4, 5, 6, 7]
})
Потім одне з наступних:
1) Три завдання в одному, використовуючи розпакування списку:
df['column_new_1'], df['column_new_2'], df['column_new_3'] = [np.nan, 'dogs', 3]
2) DataFrame
зручно розширювати один рядок, щоб відповідати індексу, так що ви можете це зробити:
df[['column_new_1', 'column_new_2', 'column_new_3']] = pd.DataFrame([[np.nan, 'dogs', 3]], index=df.index)
3) Створіть тимчасовий кадр даних з новими стовпцями, а потім об'єднайте з початковим фреймом даних пізніше:
df = pd.concat(
[
df,
pd.DataFrame(
[[np.nan, 'dogs', 3]],
index=df.index,
columns=['column_new_1', 'column_new_2', 'column_new_3']
)
], axis=1
)
4) Подібно до попереднього, але використання join
замість concat
(можливо, менш ефективно):
df = df.join(pd.DataFrame(
[[np.nan, 'dogs', 3]],
index=df.index,
columns=['column_new_1', 'column_new_2', 'column_new_3']
))
5) Використання dict є більш "природним" способом створення нового кадру даних, ніж попередні два, але нові стовпці будуть сортовані за алфавітом (принаймні перед Python 3.6 або 3.7 ):
df = df.join(pd.DataFrame(
{
'column_new_1': np.nan,
'column_new_2': 'dogs',
'column_new_3': 3
}, index=df.index
))
6) Використовуйте .assign()
з кількома аргументами стовпців.
Мені дуже подобається цей варіант у відповіді @ нуля, але, як і в попередньому, нові стовпці завжди будуть відсортовані за алфавітом, принаймні з ранніми версіями Python:
df = df.assign(column_new_1=np.nan, column_new_2='dogs', column_new_3=3)
new_cols = ['column_new_1', 'column_new_2', 'column_new_3']
new_vals = [np.nan, 'dogs', 3]
df = df.reindex(columns=df.columns.tolist() + new_cols) # add empty cols
df[new_cols] = new_vals # multi-column assignment works for existing cols
8) Зрештою, важко перемогти три окремі завдання:
df['column_new_1'] = np.nan
df['column_new_2'] = 'dogs'
df['column_new_3'] = 3
Примітка: багато з цих параметрів уже висвітлено в інших відповідях: Додайте декілька стовпців до DataFrame та встановіть їх рівним наявному стовпцю , чи можливо додати відразу кілька стовпців до панд DataFrame? , Додайте кілька порожніх стовпців до панд DataFrame
KeyError: "None of [Index(['column_new_1', 'column_new_2', 'column_new_3'], dtype='object')] are in the [columns]"