将空列表列添加到DataFrame

vk1*_*011 21 python pandas

与此问题类似如何向数据框添加空列?,我有兴趣知道将一列空列表添加到DataFrame的最佳方法.

我要做的是基本上初始化一个列,当我遍历行来处理其中的一些时,然后在这个新列中添加一个填充列表来替换初始化值.

例如,如果以下是我的初始DataFrame:

df = pd.DataFrame(d = {'a': [1,2,3], 'b': [5,6,7]}) # Sample DataFrame

>>> df
   a  b
0  1  5
1  2  6
2  3  7
Run Code Online (Sandbox Code Playgroud)

然后我想最终得到类似的东西,其中每一行都已单独处理(显示的样本结果):

>>> df
   a  b          c
0  1  5     [5, 6]
1  2  6     [9, 0]
2  3  7  [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

当然,如果我尝试像df['e'] = []任何其他常量一样初始化,它认为我试图添加长度为0的项目序列,因此失败.

如果我尝试将新列初始化为NoneNaN,则在尝试将列表分配给某个位置时会遇到以下问题.

df['d'] = None

>>> df
   a  b     d
0  1  5  None
1  2  6  None
2  3  7  None
Run Code Online (Sandbox Code Playgroud)

问题1(如果我可以使用这种方法工作,那将是完美的!也许是我遗漏的一些微不足道的事情):

>>> df.loc[0,'d'] = [1,3]

...
ValueError: Must have equal len keys and value when setting with an iterable
Run Code Online (Sandbox Code Playgroud)

问题2(这个有效,但不是没有警告,因为它不能保证按预期工作):

>>> df['d'][0] = [1,3]

C:\Python27\Scripts\ipython:1: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame
Run Code Online (Sandbox Code Playgroud)

因此,我采用初始化空列表并根据需要进行扩展.我可以想到几种方法来初始化这种方式,但是有一种更简单的方法吗?

方法1:

df['empty_lists1'] = [list() for x in range(len(df.index))]

>>> df
   a  b   empty_lists1
0  1  5             []
1  2  6             []
2  3  7             []
Run Code Online (Sandbox Code Playgroud)

方法2:

 df['empty_lists2'] = df.apply(lambda x: [], axis=1)

>>> df
   a  b   empty_lists1   empty_lists2
0  1  5             []             []
1  2  6             []             []
2  3  7             []             []
Run Code Online (Sandbox Code Playgroud)

问题摘要:

是否可以在问题1中解决任何可以允许将列表分配给None/ NaN初始化字段的次要语法更改?

如果没有,那么用空列表初始化新列的最佳方法是什么?

Com*_*low 22

还有一种方法是使用np.empty:

df['empty_list'] = np.empty((len(df), 0)).tolist()
Run Code Online (Sandbox Code Playgroud)

你也可以收工.index你的"方法1"试图找到当lendf.

df['empty_list'] = [[] for _ in range(len(df))]
Run Code Online (Sandbox Code Playgroud)

事实证明,np.empty更快......

In [1]: import pandas as pd

In [2]: df = pd.DataFrame(pd.np.random.rand(1000000, 5))

In [3]: timeit df['empty1'] = pd.np.empty((len(df), 0)).tolist()
10 loops, best of 3: 127 ms per loop

In [4]: timeit df['empty2'] = [[] for _ in range(len(df))]
10 loops, best of 3: 193 ms per loop

In [5]: timeit df['empty3'] = df.apply(lambda x: [], axis=1)
1 loops, best of 3: 5.89 s per loop
Run Code Online (Sandbox Code Playgroud)


toz*_*CSS 8

我在接受的答案中为所有三种方法定了时间,最快的一种花费了我的机器216毫秒。但是,这仅花费了28毫秒:

df['empty4'] = [[]] * len(df)

注意:同样,df['e5'] = [set()] * len(df)也花费了28ms。

  • 所有这些列表都是同一对象。设置一个单元格将全部设置。df ['empty_list'] = [[]范围(_(len(df))中的_]更好。 (3认同)