同时向pandas添加多个列

时间:2023-01-18 20:19:32

I'm new to pandas and trying to figure out how to add multiple columns to pandas simultaneously. Any help here is appreciated. Ideally I would like to do this in one step rather than multiple repeated steps...

我是熊猫的新手,并试图弄清楚如何同时为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...

5 个解决方案

#1


38  

I would have expected your syntax to work too. The problem arises because when you create new columns with the column-list syntax (df[[new1, new2]] = ...), pandas requires that the right hand side be a DataFrame (note that it doesn't actually matter if the columns of the DataFrame have the same names as the columns you are creating).

我原本期望你的语法也能正常工作。出现问题的原因是当您使用列列表语法(df [[new1,new2]] = ...)创建新列时,pandas要求右侧是DataFrame(请注意,如果它是一个DataFrame,它实际上并不重要DataFrame的列与您正在创建的列具有相同的名称。

Your syntax works fine for assigning scalar values to existing columns, and pandas is also happy to assign scalar values to a new column using the single-column syntax (df[new1] = ...). So the solution is either to convert this into several single-column assignments, or create a suitable DataFrame for the right-hand side.

您的语法可以很好地为现有列分配标量值,并且pandas也很乐意使用单列语法(df [new1] = ...)将标量值分配给新列。因此,解决方案是将其转换为多个单列分配,或者为右侧创建合适的DataFrame。

Here are several approaches that will work:

以下是几种可行的方法:

import pandas as pd
import numpy as np

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

Then one of the following:

然后是以下之一:

(1) Technically this is three steps, but it looks like one step:

(1)从技术上讲,这是三个步骤,但看起来只有一步:

df['column_new_1'], df['column_new_2'], df['column_new_3'] = [np.nan, 'dogs', 3]

(2) DataFrame conveniently expands a single row to match the index, so you can do this:

(2)DataFrame可以方便地扩展单行以匹配索引,因此您可以这样做:

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

(3) This would work well if you make a temporary data frame with new columns, then combine with the original data frame later:

(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) Similar to the previous, but using join instead of concat (may be less efficient):

(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) This is a more "natural" way to create the new data frame than the previous two, but the new columns will be sorted alphabetically (at least before Python 3.6 or 3.7):

(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) I like this variant on @zero's answer a lot, but like the previous one, the new columns will always be sorted alphabetically, at least with early versions of Python:

(6)我很喜欢@ zero的答案中的这个变体,但是和前一个一样,新列将始终按字母顺序排序,至少在早期版本的Python中:

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

(7) This is interesting (based on https://*.com/a/44951376/3830997), but I don't know when it would be worth the trouble:

(7)这很有意思(基于https://*.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) In the end it's hard to beat this:

(8)最后很难打败这个:

df['column_new_1'] = np.nan
df['column_new_2'] = 'dogs'
df['column_new_3'] = 3

Note: many of these options have already been covered in other answers: Add multiple columns to DataFrame and set them equal to an existing column, Is it possible to add several columns at once to a pandas DataFrame?, Pandas: Add multiple empty columns to DataFrame

注意:其他许多选项已经涵盖了其中的许多选项:向DataFrame添加多个列并将它们设置为等于现有列,是否可以一次向pandas DataFrame添加多个列?Pandas:添加多个空列到数据帧

#2


11  

You could use assign with a dict of column names and values.

您可以使用带有列名称和值的dict的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

#3


3  

With the use of concat:

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

Not very sure of what you wanted to do with [np.nan, 'dogs',3]. Maybe now set them as default values?

不太确定你想用[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

#4


1  

use of list comprehension, pd.DataFrame and pd.concat

使用list comprehension,pd.DataFrame和pd.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)

同时向pandas添加多个列

#5


0  

Just want to point out that option2 in @Matthias Fripp's answer

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

(2) I wouldn't necessarily expect DataFrame to work this way, but it does

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

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

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

is already documented in pandas' own documentation http://pandas.pydata.org/pandas-docs/stable/indexing.html#basics

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

You can pass a list of columns to [] to select columns in that order. If a column is not contained in the DataFrame, an exception will be raised. Multiple columns can also be set in this manner. You may find this useful for applying a transform (in-place) to a subset of the columns.

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

#1


38  

I would have expected your syntax to work too. The problem arises because when you create new columns with the column-list syntax (df[[new1, new2]] = ...), pandas requires that the right hand side be a DataFrame (note that it doesn't actually matter if the columns of the DataFrame have the same names as the columns you are creating).

我原本期望你的语法也能正常工作。出现问题的原因是当您使用列列表语法(df [[new1,new2]] = ...)创建新列时,pandas要求右侧是DataFrame(请注意,如果它是一个DataFrame,它实际上并不重要DataFrame的列与您正在创建的列具有相同的名称。

Your syntax works fine for assigning scalar values to existing columns, and pandas is also happy to assign scalar values to a new column using the single-column syntax (df[new1] = ...). So the solution is either to convert this into several single-column assignments, or create a suitable DataFrame for the right-hand side.

您的语法可以很好地为现有列分配标量值,并且pandas也很乐意使用单列语法(df [new1] = ...)将标量值分配给新列。因此,解决方案是将其转换为多个单列分配,或者为右侧创建合适的DataFrame。

Here are several approaches that will work:

以下是几种可行的方法:

import pandas as pd
import numpy as np

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

Then one of the following:

然后是以下之一:

(1) Technically this is three steps, but it looks like one step:

(1)从技术上讲,这是三个步骤,但看起来只有一步:

df['column_new_1'], df['column_new_2'], df['column_new_3'] = [np.nan, 'dogs', 3]

(2) DataFrame conveniently expands a single row to match the index, so you can do this:

(2)DataFrame可以方便地扩展单行以匹配索引,因此您可以这样做:

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

(3) This would work well if you make a temporary data frame with new columns, then combine with the original data frame later:

(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) Similar to the previous, but using join instead of concat (may be less efficient):

(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) This is a more "natural" way to create the new data frame than the previous two, but the new columns will be sorted alphabetically (at least before Python 3.6 or 3.7):

(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) I like this variant on @zero's answer a lot, but like the previous one, the new columns will always be sorted alphabetically, at least with early versions of Python:

(6)我很喜欢@ zero的答案中的这个变体,但是和前一个一样,新列将始终按字母顺序排序,至少在早期版本的Python中:

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

(7) This is interesting (based on https://*.com/a/44951376/3830997), but I don't know when it would be worth the trouble:

(7)这很有意思(基于https://*.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) In the end it's hard to beat this:

(8)最后很难打败这个:

df['column_new_1'] = np.nan
df['column_new_2'] = 'dogs'
df['column_new_3'] = 3

Note: many of these options have already been covered in other answers: Add multiple columns to DataFrame and set them equal to an existing column, Is it possible to add several columns at once to a pandas DataFrame?, Pandas: Add multiple empty columns to DataFrame

注意:其他许多选项已经涵盖了其中的许多选项:向DataFrame添加多个列并将它们设置为等于现有列,是否可以一次向pandas DataFrame添加多个列?Pandas:添加多个空列到数据帧

#2


11  

You could use assign with a dict of column names and values.

您可以使用带有列名称和值的dict的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

#3


3  

With the use of concat:

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

Not very sure of what you wanted to do with [np.nan, 'dogs',3]. Maybe now set them as default values?

不太确定你想用[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

#4


1  

use of list comprehension, pd.DataFrame and pd.concat

使用list comprehension,pd.DataFrame和pd.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)

同时向pandas添加多个列

#5


0  

Just want to point out that option2 in @Matthias Fripp's answer

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

(2) I wouldn't necessarily expect DataFrame to work this way, but it does

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

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

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

is already documented in pandas' own documentation http://pandas.pydata.org/pandas-docs/stable/indexing.html#basics

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

You can pass a list of columns to [] to select columns in that order. If a column is not contained in the DataFrame, an exception will be raised. Multiple columns can also be set in this manner. You may find this useful for applying a transform (in-place) to a subset of the columns.

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