如何在一次分配中添加多个列到熊猫数据框架?

我是熊猫的新手,试图弄清楚如何同时向熊猫添加多个列。任何帮助都是感激的。理想情况下,我希望在一个步骤中做到这一点,而不是重复多个步骤……

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...
393511 次浏览

通过使用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

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

使用列表理解,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

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

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

df[[‘column_new_1’,‘column_new_2’,‘column_new_3]] = pd.DataFrame ([[np。Nan, 'dogs', 3]], index=df.index)

已经记录在pandas自己的文档中 http://pandas.pydata.org/pandas-docs/stable/indexing.html#basics < / p >

您可以将列列表传递给[]以按此顺序选择列。 如果数据帧中不包含列,则会引发异常。 也可以通过这种方式设置多个列。 你可能会发现这对于将转换(就地)应用到列的子集很有用

你可以将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

如果用相同的值添加很多缺失的列(a, b, c,....),这里是0,我这样做:

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

这是基于公认答案的第二种变体。

如果你只是想添加空的新列,重建索引将完成这项工作

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

否则,使用分配进行0回答

我不习惯使用“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')

如果您希望每个列都有不同的值,则可以实例化字典中的值。你不介意在行前做一本字典。

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

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

使用.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)
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

在编写Pandas时,我的目标是编写可以链接的高效可读代码。我不会解释为什么我这么喜欢这里的链接,我在我的书中详细说明,有效的熊猫

我经常希望以简洁的方式添加新列,这也允许我进行链接。我的一般规则是使用.assign方法更新或创建列。

为了回答你的问题,我将使用以下代码:

(df
.assign(column_new_1=np.nan,
column_new_2='dogs',
column_new_3=3
)
)

再深入一点。我经常有一个数据框架,其中有我想要添加到我的数据框架的新列。让我们假设它看起来像…一个你想要的三列的数据框架:

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

在这种情况下,我将编写以下代码:

(df
.assign(**df2)
)

你可以使用元组解包:

df = pd.DataFrame({'col1': [1, 2], 'col2': [3, 4]})


df['col3'], df['col4'] = 'a', 10

结果:

   col1  col2 col3  col4
0     1     3    a    10
1     2     4    a    10