我试图弄清楚如何同时添加多个列的熊猫与熊猫。我希望在一个步骤中做到这一点,而不是重复多个步骤。

import pandas as pd

df = {'col_1': [0, 1, 2, 3],
        'col_2': [4, 5, 6, 7]}
df = pd.DataFrame(df)

df[[ 'column_new_1', 'column_new_2','column_new_3']] = [np.nan, 'dogs',3]  # I thought this would work here...

当前回答

我希望您的语法也能正常工作。问题出现了,因为当您使用列列表语法(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数据框架中添加多个空列

其他回答

import pandas as pd
df = pd.DataFrame({
 'col_1': [0, 1, 2, 3], 
 'col_2': [4, 5, 6, 7]
 })
df['col_3'],  df['col_4'] =  [df.col_1]*2

>> df
col_1   col_2   col_3   col_4
0      4       0       0
1      5       1       1
2      6       2       2
3      7       3       3

你可以对列名和值的字典使用赋值。

In [1069]: df.assign(**{'col_new_1': np.nan, 'col2_new_2': 'dogs', 'col3_new_3': 3})
Out[1069]:
   col_1  col_2 col2_new_2  col3_new_3  col_new_1
0      0      4       dogs           3        NaN
1      1      5       dogs           3        NaN
2      2      6       dogs           3        NaN
3      3      7       dogs           3        NaN

你可以实例化一个字典的值,如果你想为每一列不同的值&你不介意在行之前创建一个字典。

>>> import pandas as pd
>>> import numpy as np
>>> df = pd.DataFrame({
  'col_1': [0, 1, 2, 3], 
  'col_2': [4, 5, 6, 7]
})
>>> df
   col_1  col_2
0      0      4
1      1      5
2      2      6
3      3      7
>>> cols = {
  'column_new_1':np.nan,
  'column_new_2':'dogs',
  'column_new_3': 3
}
>>> df[list(cols)] = pd.DataFrame(data={k:[v]*len(df) for k,v in cols.items()})
>>> df
   col_1  col_2  column_new_1 column_new_2  column_new_3
0      0      4           NaN         dogs             3
1      1      5           NaN         dogs             3
2      2      6           NaN         dogs             3
3      3      7           NaN         dogs             3

不一定比公认的答案更好,但这是另一种尚未列出的方法。

我不习惯使用“Index”等等。可以如下所示

df.columns
Index(['A123', 'B123'], dtype='object')

df=pd.concat([df,pd.DataFrame(columns=list('CDE'))])

df.rename(columns={
    'C':'C123',
    'D':'D123',
    'E':'E123'
},inplace=True)


df.columns
Index(['A123', 'B123', 'C123', 'D123', 'E123'], dtype='object')

我希望您的语法也能正常工作。问题出现了,因为当您使用列列表语法(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数据框架中添加多个空列