Pandas:向DataFrame添加多个空列

Win*_*ags 54 python pandas

这可能是一个愚蠢的问题,但如何从列表中向DataFrame添加多个空列?

我可以:

df["B"] = None
df["C"] = None
df["D"] = None
Run Code Online (Sandbox Code Playgroud)

但我做不到:

df[["B", "C", "D"]] = None

KeyError: "['B' 'C' 'D'] not in index"
Run Code Online (Sandbox Code Playgroud)

unu*_*tbu 58

您可以使用df.reindex添加新列:

In [18]: df = pd.DataFrame(np.random.randint(10, size=(5,1)), columns=['A'])

In [19]: df
Out[19]: 
   A
0  4
1  7
2  0
3  7
4  6

In [20]: df.reindex(columns=list('ABCD'))
Out[20]: 
   A   B   C   D
0  4 NaN NaN NaN
1  7 NaN NaN NaN
2  0 NaN NaN NaN
3  7 NaN NaN NaN
4  6 NaN NaN NaN
Run Code Online (Sandbox Code Playgroud)

reindex 将返回一个新的DataFrame,列按列出的顺序显示:

In [31]: df.reindex(columns=list('DCBA'))
Out[31]: 
    D   C   B  A
0 NaN NaN NaN  4
1 NaN NaN NaN  7
2 NaN NaN NaN  0
3 NaN NaN NaN  7
4 NaN NaN NaN  6
Run Code Online (Sandbox Code Playgroud)

reindex方法也作为fill_value参数:

In [22]: df.reindex(columns=list('ABCD'), fill_value=0)
Out[22]: 
   A  B  C  D
0  4  0  0  0
1  7  0  0  0
2  0  0  0  0
3  7  0  0  0
4  6  0  0  0
Run Code Online (Sandbox Code Playgroud)

  • @MarcoSpinaci:我建议永远不要使用`inplace = True`.它并没有像大多数人认为的那样做.在引擎盖下,始终会创建一个全新的DataFrame,然后将新DataFrame中的数据复制到原始DataFrame中.这不会节省任何记忆.所以`inplace = True`是没有实质内容的橱窗,而且是误导性地命名.我没有检查过代码,但我希望`df = df.reindex(...)`需要至少2倍于`df`所需的内存,当然`更多``reindex`用于扩展数量行. (4认同)
  • 在试验了一个中等大的数据帧(80k列的~2.5k行)之后,这个解决方案似乎比接受的解决方案快了几个数量级.BTW是否有一个原因,为什么这个特定的命令不接受"inplace = True" "参数?df = df.reindex(...)似乎耗尽了相当多的RAM. (3认同)

EdC*_*ica 49

concat使用的是DataFrame:

In [23]:
df = pd.DataFrame(columns=['A'])
df

Out[23]:
Empty DataFrame
Columns: [A]
Index: []

In [24]:    
pd.concat([df,pd.DataFrame(columns=list('BCD'))])

Out[24]:
Empty DataFrame
Columns: [A, B, C, D]
Index: []
Run Code Online (Sandbox Code Playgroud)

因此,通过传递包含原始df的列表,以及包含您要添加的列的新列表,这将返回带有其他列的新df.


警告:请参阅其他答案和/或评论讨论中的性能讨论.reindex在性能至关重要的情况下可能更好.

  • 你需要分配concat的结果,所以`df = pd.concat([df,pd.DataFrame(columns = list('BCD'))])` (2认同)

tot*_*ico 22

如果您不想重写旧列的名称,则可以使用reindex:

df.reindex(columns=[*df.columns.tolist(), 'new_column1', 'new_column2'], fill_value=0)
Run Code Online (Sandbox Code Playgroud)

完整示例:

In [1]: df = pd.DataFrame(np.random.randint(10, size=(3,1)), columns=['A'])

In [1]: df
Out[1]: 
   A
0  4
1  7
2  0

In [2]: df.reindex(columns=[*df.columns.tolist(), 'col1', 'col2'], fill_value=0)
Out[2]: 

   A  col1  col2
0  1     0     0
1  2     0     0
Run Code Online (Sandbox Code Playgroud)

而且,如果您已经有一个包含列名的列表,那么:

In [3]: my_cols_list=['col1','col2']

In [4]: df.reindex(columns=[*df.columns.tolist(), *my_cols_list], fill_value=0)
Out[4]: 
   A  col1  col2
0  1     0     0
1  2     0     0
Run Code Online (Sandbox Code Playgroud)

  • 谢谢。你能告诉我`reindex`输入中的`*`是什么吗? (2认同)
  • 它将列表解压缩为位置参数,它是[Python运算符](/sf/ask/204529321/#2921893) (2认同)

Myk*_*tko 7

您可以利用Pandas 广播

df = pd.DataFrame({'A': [1, 1, 1]})

df[['B', 'C']] = 2, 3
# df[['B', 'C']] = [2, 3]
Run Code Online (Sandbox Code Playgroud)

结果:

   A  B  C
0  1  2  3
1  1  2  3
2  1  2  3
Run Code Online (Sandbox Code Playgroud)

要添加空列:

df[['B', 'C', 'D']] = 3 * [np.nan]
Run Code Online (Sandbox Code Playgroud)

结果:

   A   B   C   D
0  1 NaN NaN NaN
1  1 NaN NaN NaN
2  1 NaN NaN NaN
Run Code Online (Sandbox Code Playgroud)


ale*_*ice 6

为什么不直接使用循环:

for newcol in ['B','C','D']:
    df[newcol]=np.nan
Run Code Online (Sandbox Code Playgroud)


yos*_*e_k 6

替代解决方案摘要:

columns_add = ['a', 'b', 'c']
Run Code Online (Sandbox Code Playgroud)
  1. for循环:

    for newcol in columns_add:
        df[newcol]= None
    
    Run Code Online (Sandbox Code Playgroud)
  2. 字典方法:

    df.assign(**dict([(_,None) for _ in columns_add]))
    
    Run Code Online (Sandbox Code Playgroud)
  3. 元组赋值:

    df['a'], df['b'], df['c'] = None, None, None
    
    Run Code Online (Sandbox Code Playgroud)