同时向pandas添加多个列

时间:2016-08-20 04:40:50

标签: python pandas

我是pandas的新手,并试图找出如何同时向pandas添加多个列。任何帮助在这里表示赞赏。理想情况下,我想一步到位而不是多次重复步骤......

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]  #thought this would work here...

11 个答案:

答案 0 :(得分:84)

我原本希望你的语法也能正常工作。出现问题是因为当您使用列列表语法(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)这是一个更自然的"创建新数据框的方法比前两个,但新列将按字母顺序排序(至少before Python 3.6 or 3.7):

df = df.join(pd.DataFrame(
    {
        'column_new_1': np.nan,
        'column_new_2': 'dogs',
        'column_new_3': 3
    }, index=df.index
))

(6)我喜欢@ zero的答案很多,但与前一个一样,新列将始终按字母顺序排序,至少在早期版本的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

注意:其他答案中已涵盖了其中许多选项:Add multiple columns to DataFrame and set them equal to an existing columnIs it possible to add several columns at once to a pandas DataFrame?Pandas: Add multiple empty columns to DataFrame

答案 1 :(得分:23)

您可以将assign与列名和值的字典一起使用。

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

答案 2 :(得分:3)

使用concat

In [128]: df
Out[128]: 
   col_1  col_2
0      0      4
1      1      5
2      2      6
3      3      7

In [129]: pd.concat([df, pd.DataFrame(columns = [ 'column_new_1', 'column_new_2','column_new_3'])])
Out[129]: 
   col_1  col_2 column_new_1 column_new_2 column_new_3
0    0.0    4.0          NaN          NaN          NaN
1    1.0    5.0          NaN          NaN          NaN
2    2.0    6.0          NaN          NaN          NaN
3    3.0    7.0          NaN          NaN          NaN

不太确定您想要对[np.nan, 'dogs',3]做些什么。也许现在将它们设置为默认值?

In [142]: df1 = pd.concat([df, pd.DataFrame(columns = [ 'column_new_1', 'column_new_2','column_new_3'])])
In [143]: df1[[ 'column_new_1', 'column_new_2','column_new_3']] = [np.nan, 'dogs', 3]

In [144]: df1
Out[144]: 
   col_1  col_2  column_new_1 column_new_2  column_new_3
0    0.0    4.0           NaN         dogs             3
1    1.0    5.0           NaN         dogs             3
2    2.0    6.0           NaN         dogs             3
3    3.0    7.0           NaN         dogs             3

答案 3 :(得分:3)

使用列表理解,pd.DataFramepd.concat

pd.concat(
    [
        df,
        pd.DataFrame(
            [[np.nan, 'dogs', 3] for _ in range(df.shape[0])],
            df.index, ['column_new_1', 'column_new_2','column_new_3']
        )
    ], axis=1)

enter image description here

答案 4 :(得分:0)

只想在@Matthias Fripp的回答中指出选项2

  

(2)我不一定希望DataFrame以这种方式工作,但确实如此

     

df [[' column_new_1',' column_new_2',' column_new_3']] = pd.DataFrame([[np.nan,' dogs& #39;,3]],index = df.index)

已经记录在熊猫'自己的文件 http://pandas.pydata.org/pandas-docs/stable/indexing.html#basics

  

您可以将列列表传递给[]以按顺序选择列。   如果DataFrame中未包含列,则会引发异常。   也可以这种方式设置多列。   您可能会发现这对将变换(就地)应用于列的子集非常有用。

答案 5 :(得分:0)

df = pd.DataFrame(columns = ['column1','column2'])

答案 6 :(得分:0)

如果添加许多具有相同值的缺失列(a,b,c,....),这里为0,我这样做:

    new_cols = ["a", "b", "c" ] 
    df[new_cols] = pd.DataFrame([[0] * len(new_cols)], index=df.index)

它基于已接受答案的第二个变体。

答案 7 :(得分:0)

如果您只想添加空的新列,reindex将会完成

df
   col_1  col_2
0      0      4
1      1      5
2      2      6
3      3      7

df.reindex(list(df)+['column_new_1', 'column_new_2','column_new_3'], axis=1)
   col_1  col_2  column_new_1  column_new_2  column_new_3
0      0      4           NaN           NaN           NaN
1      1      5           NaN           NaN           NaN
2      2      6           NaN           NaN           NaN
3      3      7           NaN           NaN           NaN

完整代码示例

import numpy as np
import pandas as pd

df = {'col_1': [0, 1, 2, 3],
        'col_2': [4, 5, 6, 7]}
df = pd.DataFrame(df)
print('df',df, sep='\n')
print()
df=df.reindex(list(df)+['column_new_1', 'column_new_2','column_new_3'], axis=1)
print('''df.reindex(list(df)+['column_new_1', 'column_new_2','column_new_3'], axis=1)''',df, sep='\n')

否则,用zeros来回答assign

答案 8 :(得分:0)

我不习惯使用“索引”,依此类推...可能如下所示

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')

答案 9 :(得分:0)

如果您想为每一列使用不同的值,并且不介意在之前的行中创建字典,则可以实例化字典中的值。

>>> 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

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

答案 10 :(得分:0)

使用 .assign() 进行字典映射:

这是在处理许多列时为新列分配值的最易读和最动态的方式。

import pandas as pd
import numpy as np

new_cols = ["column_new_1", "column_new_2", "column_new_3"]
new_vals = [np.nan, "dogs", 3]
# Map new columns as keys and new values as values
col_val_mapping = dict(zip(new_cols, new_vals))
# Unpack new column/new value pairs and assign them to the data frame
df = df.assign(**col_val_mapping)

如果您只是想将新列的值初始化为空,因为您要么不知道这些值将是什么,要么您有许多新列。

import pandas as pd
import numpy as np

new_cols = ["column_new_1", "column_new_2", "column_new_3"]
new_vals = [None for item in new_cols]
# Map new columns as keys and new values as values
col_val_mapping = dict(zip(new_cols, new_vals))
# Unpack new column/new value pairs and assign them to the data frame
df = df.assign(**col_val_mapping)