【问题标题】:How to add an empty column to a dataframe?如何将空列添加到数据框?
【发布时间】:2013-04-25 23:26:28
【问题描述】:

向 pandas DataFrame 对象添加空列的最简单方法是什么?我偶然发现的最好的东西是

df['foo'] = df.apply(lambda _: '', axis=1)

有没有不那么反常的方法?

【问题讨论】:

  • 你真的想要一个包含空字符串的列还是N/A
  • 您能否解释一下为什么要创建一个空列而不是仅仅组装一个值列表并在最后直接分配?

标签: python pandas


【解决方案1】:

如果我理解正确,作业应该填写:

>>> import numpy as np
>>> import pandas as pd
>>> df = pd.DataFrame({"A": [1,2,3], "B": [2,3,4]})
>>> df
   A  B
0  1  2
1  2  3
2  3  4
>>> df["C"] = ""
>>> df["D"] = np.nan
>>> df
   A  B C   D
0  1  2   NaN
1  2  3   NaN
2  3  4   NaN

【讨论】:

  • 这个答案刚刚为我创建了新行。
  • @logicboke 你能提供一个发生这种情况的例子吗?
  • 如果df 为空,您可能需要使用df['new'] = pd.Series()(请参阅下面的答案)
  • 如何添加多个空列?
  • @M.Mariscal df[["newcol1","newcol2","newcol3"]] = None.
【解决方案2】:

为了补充 DSM 的答案并以 @​​987654321@ 为基础,我将方法分为两种情况:

  • 添加单列:只需为新列分配空值,例如df['C'] = np.nan

  • 添加多个列:我建议使用 .reindex(columns=[...]) method of pandas 将新列添加到数据框的列索引中。这也适用于使用.reindex(rows=[...]) 添加多个新行。请注意,较新版本的 Pandas (v>0.20) 允许您指定 axis 关键字,而不是显式分配给 columnsrows

这是一个添加多列的示例:

mydf = mydf.reindex(columns = mydf.columns.tolist() + ['newcol1','newcol2'])

mydf = mydf.reindex(mydf.columns.tolist() + ['newcol1','newcol2'], axis=1)  # version > 0.20.0

您也可以始终将一个新的(空)数据框连接到现有的数据框,但这对我来说并不像 pythonic :)

【讨论】:

  • version >= 0.20.0 的示例删除 DataFrame 并将新列添加为行。 version < 0.20.0 的示例在 Pandas 版本 0.24.1 上运行良好
  • @emunsing 在寻找这个问题的答案时,我最终发现您的回答很有帮助。然而,起初它对我不起作用,因为 Pandas 在version = 0.25 中需要, axis=1。我试图修改您的答案以包含更新的版本,但被@kenlukas 和@il_raffa 拒绝。我希望每个努力理解为什么你的回复对他们不起作用的人——就像我一样——至少看到这条评论。
  • @Griff - 我现在更新了我的答案,以更准确和明确地说明版本兼容性问题。感谢您强调这一点。
【解决方案3】:

一个更简单的解决方案是:

df = df.reindex(columns = header_list)                

其中“header_list”是您想要显示的标题列表。

列表中包含的任何未在数据框中找到的标题都将在下面添加空白单元格。

如果

header_list = ['a','b','c', 'd']

然后 c 和 d 将被添加为带有空白单元格的列

【讨论】:

  • 更准确地说,列将添加 NaN。
【解决方案4】:

我喜欢:

df['new'] = pd.Series(dtype='int')

# or use other dtypes like 'float', 'object', ...

如果您有一个空数据框,此解决方案可确保不会添加仅包含 NaN 的新行。

指定dtype 不是绝对必要的,但是如果未指定,较新的 Pandas 版本会生成DeprecationWarning

【讨论】:

  • 这是插入具有预定义 dtype 的新列的最佳方式。
【解决方案5】:

v0.16.0 开始,DF.assign() 可用于将新列(单个/多个)分配给DF。这些列按字母顺序插入到DF 的末尾。

在您想直接在返回的数据帧上执行一系列链接操作的情况下,与简单分配相比,这变得有利。

考虑@DSM 演示的相同DF 示例:

df = pd.DataFrame({"A": [1,2,3], "B": [2,3,4]})
df
Out[18]:
   A  B
0  1  2
1  2  3
2  3  4

df.assign(C="",D=np.nan)
Out[21]:
   A  B C   D
0  1  2   NaN
1  2  3   NaN
2  3  4   NaN

请注意,这将返回包含所有先前列以及新创建的列的副本。为了对原来的DF进行相应的修改,像df = df.assign(...)一样使用它,因为它目前不支持inplace操作。

【讨论】:

  • C 的数据类型是什么?我试图通过循环遍历字符串列表来添加。但它不使用它。
【解决方案6】:

如果你想从列表中添加列名

df=pd.DataFrame()
a=['col1','col2','col3','col4']
for i in a:
    df[i]=np.nan

【讨论】:

    【解决方案7】:

    @emunsing 的answer 非常适合添加多列,但我无法让它在 python 2.7 中为我工作。相反,我发现这是可行的:

    mydf = mydf.reindex(columns = np.append( mydf.columns.values, ['newcol1','newcol2'])
    

    【讨论】:

      【解决方案8】:

      这也适用于多列:

      df = pd.DataFrame({"A": [1,2,3], "B": [2,3,4]})
      >>> df
         A  B
      0  1  2
      1  2  3
      2  3  4
      
      df1 = pd.DataFrame(columns=['C','D','E'])
      df = df.join(df1, how="outer")
      
      >>>df
          A   B   C   D   E
      0   1   2   NaN NaN NaN
      1   2   3   NaN NaN NaN
      2   3   4   NaN NaN NaN
      

      然后对列做任何你想做的事情 pd.Series.fillna(),pd.Series.map() 等等

      【讨论】:

      【解决方案9】:

      可以使用df.insert(index_to_insert_at, column_header, init_value) 在特定索引处插入新列。

      cost_tbl.insert(1, "col_name", "") 
      

      上述语句将在第一列之后插入一个空列。

      【讨论】:

        【解决方案10】:

        以下代码解决了“如何将 n 个空列添加到现有数据框”的问题。为了将类似问题的解决方案保存在一个地方,我将其添加到此处。

        方法 1(创建 64 个附加列,列名称为 1-64)

        m = list(range(1,65,1)) 
        dd=pd.DataFrame(columns=m)
        df.join(dd).replace(np.nan,'') #df is the dataframe that already exists
        

        方法 2(创建 64 个附加列,列名从 1 到 64)

        df.reindex(df.columns.tolist() + list(range(1,65,1)), axis=1).replace(np.nan,'')
        

        【讨论】:

          【解决方案11】:

          你可以的

          df['column'] = None #This works. This will create a new column with None type
          df.column = None #This will work only when the column is already present in the dataframe 
          

          【讨论】:

            【解决方案12】:

            抱歉,我一开始没有很好地解释我的答案。还有另一种方法可以将新列添加到现有数据框中。 第一步,创建一个名为 df_temp 的新空数据框(包含数据框中的所有列,以及要添加的新列或几列) 第二步,结合 df_temp 和你的数据框。

            df_temp = pd.DataFrame(columns=(df_null.columns.tolist() + ['empty']))
            df = pd.concat([df_temp, df])
            

            这可能是最好的解决方案,但这是思考这个问题的另一种方式。

            我使用这种方法的原因是因为我一直收到这个警告:

            : SettingWithCopyWarning: 
            A value is trying to be set on a copy of a slice from a DataFrame.
            Try using .loc[row_indexer,col_indexer] = value instead
            
            See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
              df["empty1"], df["empty2"] = [np.nan, ""]
            

            太好了,我找到了禁用警告的方法

            pd.options.mode.chained_assignment = None 
            

            【讨论】:

            • 好的,所以...请确保在给出答案时,请逐行提供有关正在发生的事情的一些信息。因为问这个问题的人不会从中吸取教训,他会吗?他将复制和粘贴,他的代码将工作,他不会知道为什么。所以我建议添加更多信息。
            • @SimasJoneliunas 审稿时请注意。这不是仅链接的答案。
            • 确实,我误点击了审核队列中的标志。以后我会更加小心的。我对删除此答案的投票仍然是仅代码答案。
            【解决方案13】:

            我寻找这种解决方案的原因只是在多个 DF 之间添加空格,这些 DF 已使用 pd.concat 函数按列连接,然后使用 xlsxwriter 写入 excel。

            df[' ']=df.apply(lambda _: '', axis=1)
            df_2 = pd.concat([df,df1],axis=1)                #worked but only once. 
            # Note: df & df1 have the same rows which is my index. 
            #
            df_2[' ']=df_2.apply(lambda _: '', axis=1)       #didn't work this time !!?     
            df_4 = pd.concat([df_2,df_3],axis=1)
            

            然后我将第二个 lambda 调用替换为

            df_2['']=''                                 #which appears to add a blank column
            df_4 = pd.concat([df_2,df_3],axis=1)
            

            我测试它的输出是使用 xlsxwriter 来表现出色。 Jupyter 空白列看起来与 excel 中的相同,但没有 xlsx 格式。 不知道为什么第二个 Lambda 调用不起作用。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2018-10-26
              • 1970-01-01
              • 1970-01-01
              • 2014-12-28
              • 1970-01-01
              • 2022-01-05
              • 2017-07-30
              相关资源
              最近更新 更多