如何添加一个空列到一个数据框架?

向pandas DataFrame对象中添加空列的最简单方法是什么?我碰到的最好的是

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

有没有更合理的方法?

889824 次浏览

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

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

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操作。

@emunsing的回答对于添加多列来说真的很酷,但我在python 2.7中无法让它为我工作。相反,我发现这个方法很有效:

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

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

df = df.reindex(columns = header_list)

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

列表中包含的任何标题,如果在数据帧中没有找到,将在下面添加空白单元格。

因此,如果

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

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

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

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

我喜欢:

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


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

如果你有一个空的数据框架,这个解决方案确保没有新行只包含NaN被添加。

指定dtype并不是必须的,但是如果没有指定,更新的Pandas版本会生成DeprecationWarning

下面的代码解决了“如何向现有数据框架中添加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,'')

你可以这样做

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

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

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

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

对不起,我一开始没有把我的答案解释得很好。还有另一种方法可以将新列添加到现有数据框架中。 第一步,创建一个新的空数据帧(包含数据帧中的所有列,加上您想添加的新列或少数列),称为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

我寻找这样一个解决方案的原因只是在多个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到excel。 Jupyter空白列看起来和excel一样,虽然没有xlsx格式。 不知道为什么第二个Lambda调用没有工作

这也适用于多个列:

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() 等。< / p >

如果你有一个列列表,你想要为空,你可以使用assign,然后理解字典,然后字典解包。

>>> df = pd.DataFrame({"A": [1,2,3], "B": [2,3,4]})
>>> nan_cols_name = ["C","D","whatever"]
>>> df.assign(**{col:np.nan for col in nan_cols_name})


A  B   C   D  whatever
0  1  2 NaN NaN       NaN
1  2  3 NaN NaN       NaN
2  3  4 NaN NaN       NaN

如果希望不同列有不同的值,还可以在解包的字典中解包多个字典。

df = pd.DataFrame({"A": [1,2,3], "B": [2,3,4]})
nan_cols_name = ["C","D","whatever"]
empty_string_cols_name = ["E","F","bad column with space"]
df.assign(**{
**{col:np.nan for col in my_empy_columns_name},
**{col:"" for col in empty_string_cols_name}
}
)
df["C"] = ""
df["D"] = np.nan

赋值函数会给你这样的警告SettingWithCopyWarning:

一个值正在试图从一个数据帧(DataFrame)中设置一个片的副本。试一试 使用.loc[row_indexer,col_indexer] = value代替

所以最好使用插入:

df.insert(index, column-name, column-value)