如何从列表中向 DataFrame
添加多个空列?
我可以这样做:
df["B"] = None
df["C"] = None
df["D"] = None
但是我做不到:
df[["B", "C", "D"]] = None
KeyError: "['B' 'C' 'D'] not in index"
您可以使用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
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
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
inplace=True
。它的作用不是大多数人所认为的那样。在幕后,总是创建一个全新的DataFrame,然后将新DataFrame中的数据复制到原来的DataFrame中。这并没有节省任何内存。因此, inplace=True
是华而不实的,而且名称具有误导性。我没有检查过代码,但我预计 df = df.reindex(...)
至少需要2倍于 df
所需的内存,当使用 reindex
来扩展行数时,内存会更多地被使用。 - unutbu我会使用DataFrame来concat
:
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: []
通过传递一个包含原始 df 和一个新 df 的列表,其中包含您希望添加的列,这将返回一个具有附加列的新 df。
reindex
。如果您不想重写旧列的名称,那么可以使用reindex:
df.reindex(columns=[*df.columns.tolist(), 'new_column1', 'new_column2'], fill_value=0)
完整示例:
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
如果您已经有一份列名清单,那么:
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
备选方案摘要:
columns_add = ['a', 'b', 'c']
for循环:
for newcol in columns_add:
df[newcol]= None
字典方法:
df.assign(**dict([(_,None) for _ in columns_add]))
元组赋值:
df['a'], df['b'], df['c'] = None, None, None
df.assign(**dict.fromkeys(columns_add, None))
应该也可以工作。 - Joe Ferndz为什么不直接使用循环:
for newcol in ['B','C','D']:
df[newcol]=np.nan
df = pd.DataFrame({'A': [1, 1, 1]})
df[['B', 'C']] = 2, 3
# df[['B', 'C']] = [2, 3]
结果:
A B C
0 1 2 3
1 1 2 3
2 1 2 3
添加空列:
df[['B', 'C', 'D']] = 3 * [np.nan]
结果:
A B C D
0 1 NaN NaN NaN
1 1 NaN NaN NaN
2 1 NaN NaN NaN
我会使用
df["B"], df["C"], df["D"] = None, None, None
df["B"], df["C"], df["D"] = ["None" for a in range(3)]
columns_add = ['a', 'b', 'c']
df = df.assign(**dict(zip(columns_add, [0] * len(columns_add)))
None
和0是不同的,但有些答案假定它们是等价的。此外,赋值为None
将会得到一个对象类型(dtype),而赋值为0将会得到一个整数类型(dtype)。 - smcidf[['B','C','D']] = None, None, None
或[None, None, None]
或pd.DataFrame([None, None, None])
。 - smci