如何在一次分配中向pandas数据框添加多列

2025-01-20 09:07:00
admin
原创
104
摘要:问题描述:我正在尝试弄清楚如何使用 Pandas 同时向 pandas 添加多列。我希望一步完成此操作,而不是重复多个步骤。import pandas as pd data = {'col_1': [0, 1, 2, 3], 'col_2': [4, 5, 6, 7]} df = pd.Da...

问题描述:

我正在尝试弄清楚如何使用 Pandas 同时向 pandas 添加多列。我希望一步完成此操作,而不是重复多个步骤。

import pandas as pd

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

我认为这在这里会起作用......

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

解决方案 1:

我原本以为你的语法也能正常工作。问题出现是因为当你使用 column-list 语法 ( 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)使用以下方法与临时 DataFrame 结合pd.concat

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)使用以下方法与临时 DataFrame 结合.join

这与3类似,但效率可能较低。

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

5)使用字典代替3和4中使用的列表

与前两种方法相比,这是一种更“自然”的创建临时 DataFrame 的方法。请注意,在Python 3.5 或更早版本中,新列将按字母顺序排序。

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

6)使用.assign()多列参数

这可能是 Python 3.6+ 中的赢家。但与上一个一样,在早期版本的 Python 中,新列将按字母顺序排序。

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

7)创建新列,然后一次性分配所有值

根据这个答案。这很有趣,但我不知道什么时候才值得这么麻烦。

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 DataFrame 添加多个空列

解决方案 2:

您可以使用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:

我编写 Pandas 的目标是编写可链式调用的高效可读代码。我不会在这里解释我为什么如此喜欢链式调用,我在我的书《Effective 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)
)

解决方案 4:

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

解决方案 5:

字典映射.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)

解决方案 6:

使用列表推导,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)

在此处输入图片描述

解决方案 7:

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

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

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

解决方案 8:

您可以使用元组解包:

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

解决方案 9:

只是想指出@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

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

解决方案 10:

如果你只想添加空的新列,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='
')
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='
')

否则用分配来获取零答案

解决方案 11:

我不太习惯使用“索引”等...可能会出现如下情况

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

解决方案 12:

如果您希望为每一列设置不同的值,并且不介意在之前的行上创建一个字典,那么您可以从字典中实例化这些值。

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

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

解决方案 13:

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

解决方案 14:

我尝试了你原来的方法(你说的那个对你不起作用的方法)并且它对我来说效果很好,至少在我的 pandas 版本(1.5.2)中

import pandas as pd
import numpy as np

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

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

这是我得到的:

1.5.2
   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

但还有一种更酷、更通用的方法

由于您可能希望在添加新列时使用一些逻辑,因此一次性向数据框添加新列*的另一种方法是应用具有所需逻辑的逐行函数。在您的示例中:

def add_3_new_fields_to_each_row(row: pd.Series) -> pd.Series:
    """ Adding 3 new fields to each row of a dataframe is the same as 
    adding 3 new columns to the dataframe """
    row['column_new_1'] = np.nan
    row['column_new_2'] = 'dogs'
    row['column_new_3'] = 3
    # the good thing of this approach is that you could even make the
    # values of "later" fields be dependent on the values of
    # "earlier" fields, all in one go
    return row  # this row now has 3 more fields

df = pd.DataFrame(data)
df_new = df.apply(add_3_new_fields_to_each_row, axis='columns')

这样做df虽然不会改变,但却df_new是您想要的数据框:

   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

*(实际上,它返回一个包含新列的新数据框,并且不会修改原始数据框)

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2887  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1752  
  引言PLM(产品生命周期管理)系统在企业项目管理中扮演着至关重要的角色。它涵盖了从产品概念设计到退役的整个生命周期,整合了各种数据和流程。在项目推进过程中,危机难以避免,而PLM系统凭借其强大的功能和特性,能够为项目危机管理提供全面且有效的支持。通过合理运用PLM系统,企业可以提前预防危机、在危机发生时迅速做出响应并采...
plm系统功能介绍   14  
  PLM(产品生命周期管理)系统在企业日常运营中扮演着至关重要的角色,它涵盖了产品从概念设计到退役的整个生命周期,涉及多个部门和环节。有效的系统维护能够确保PLM系统稳定运行,提升企业的生产效率、产品质量以及创新能力。以下将详细阐述PLM系统维护在日常运营中的6个关键环节。系统监控与性能优化系统监控是保障PLM系统正常运...
PLM项目管理软件   14  
  引言产品生命周期管理(PLM)系统在现代企业的运营中扮演着至关重要的角色。它不仅仅是一个管理产品数据的工具,更是推动企业持续改进的强大引擎。在追求卓越质量的道路上,PLM系统与质量工具的有效结合能够释放巨大的能量。2025年,随着市场竞争的日益激烈和客户需求的不断变化,企业需要更加深入地挖掘PLM系统的潜力,通过实践先...
免费plm管理软件   16  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用