同时向pandas添加多个列

run*_*rds 79 python 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...
Run Code Online (Sandbox Code Playgroud)

Mat*_*ipp 112

我原本期望你的语法也能正常工作.这个问题的产生是因为当你创建一个列列表语法(新列df[[new1, new2]] = ...),熊猫需要的右手边是一个数据框(请注意,它实际上并不重要,如果数据帧的列具有相同的名称列你正在创造).

您的语法可以很好地为现有列分配标量值,并且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]
})
Run Code Online (Sandbox Code Playgroud)

然后是以下之一:

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

df['column_new_1'], df['column_new_2'], df['column_new_3'] = [np.nan, 'dogs', 3]
Run Code Online (Sandbox Code Playgroud)

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

df[['column_new_1', 'column_new_2', 'column_new_3']] = pd.DataFrame([[np.nan, 'dogs', 3]], index=df.index)
Run Code Online (Sandbox Code Playgroud)

(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
)
Run Code Online (Sandbox Code Playgroud)

(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']
))
Run Code Online (Sandbox Code Playgroud)

(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
))
Run Code Online (Sandbox Code Playgroud)

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

df = df.assign(column_new_1=np.nan, column_new_2='dogs', column_new_3=3)
Run Code Online (Sandbox Code Playgroud)

(7)这很有趣(基于/sf/answers/3146596351/),但我不知道什么时候值得这么麻烦:

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
Run Code Online (Sandbox Code Playgroud)

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

df['column_new_1'] = np.nan
df['column_new_2'] = 'dogs'
df['column_new_3'] = 3
Run Code Online (Sandbox Code Playgroud)

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

  • 如果您使用“join”选项,请确保索引中没有重复项(或首先使用“reset_index”)。可能会节省您几个小时的调试时间。 (2认同)

mat*_*son 31

我编写 Pandas 时的目标是编写可以链接的高效可读代码。我不会在这里解释为什么我如此喜欢链接,我在我的书《Effective Pandas》中对此进行了阐述。

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

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

(df
 .assign(column_new_1=np.nan,
         column_new_2='dogs',
         column_new_3=3
        )
)
Run Code Online (Sandbox Code Playgroud)

还要走得更远一点。我经常有一个数据框,其中包含我想要添加到数据框的新列。让我们假设它看起来像......一个包含您想要的三列的数据框:

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

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

(df
 .assign(**df2)
)
Run Code Online (Sandbox Code Playgroud)


Zer*_*ero 30

您可以使用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
Run Code Online (Sandbox Code Playgroud)

  • 您可以通过多次调用 allocate 来维护早期版本的 Python 的特定顺序:`df.assign(**{'col_new_1': np.nan}).assign(**{'col2_new_2': 'dogs'})。分配(**{'col3_new_3': 3})` (2认同)

Neh*_*ani 6

随着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
Run Code Online (Sandbox Code Playgroud)

不太确定您想要做什么[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
Run Code Online (Sandbox Code Playgroud)