我希望您的语法也能正常工作。问题出现了,因为当您使用列列表语法(df[[new1, new2]] =…)创建新列时,pandas要求右侧是一个DataFrame(注意,DataFrame的列是否与您正在创建的列具有相同的名称实际上并不重要)。
您的语法可以很好地为现有列分配标量值,pandas也很乐意使用单列语法(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)使用字典是一种比前两种更“自然”的方式来创建新的数据帧,但新列将按字母顺序排序(至少在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()和多个列参数。
我非常喜欢@ 0的答案的这个变体,但像前一个一样,新列将始终按照字母顺序排序,至少在早期版本的Python中是这样的:
df = df.assign(column_new_1=np.nan, column_new_2='dogs', column_new_3=3)
7)这很有趣(基于https://stackoverflow.com/a/44951376/3830997),但我不知道什么时候值得这么麻烦:
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,并将它们设置为等于现有的列,是否可以一次添加几个列到pandas DataFrame?,在pandas数据框架中添加多个空列