熊猫列创建方法

时间:2018-07-26 14:22:34

标签: python python-3.x pandas dataframe

有很多方法可以在Pandas中创建新列(我可能在示例中错过了一些,所以请让我知道是否还有其他列,我将在此处包括),我想弄清楚何时是最佳使用时间每种方法。显然,某些方法在某些情况下要比其他方法更好,但我想从整体观点来评估它,即效率可读性有用性

我主要关注的是前三个,但包括其他方法只是为了说明使用不同方法的可能性。这是您的示例dataframe

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

最常见的方式是命名一个新列,例如df['c']并使用apply

df['c'] = df['a'].apply(lambda x: x * 2)
df
   a  b  c
0  1  4  2
1  2  5  4
2  3  6  6

使用assign可以完成同样的事情:

df = df.assign(c = lambda x: x['a'] * 2)
df
   a  b  c
0  1  4  2
1  2  5  4
2  3  6  6

通过@roganjosh更新:

df['c'] = df['a'] * 2
df
   a  b  c
0  1  4  2
1  2  5  4
2  3  6  6

使用map(肯定不如apply高效):

df['c'] = df['a'].map(lambda x: x * 2)
df
   a  b  c
0  1  4  2
1  2  5  4
2  3  6  6

先创建一个新的pd.series,然后再创建concat,将其放入dataframe

c = pd.Series(df['a'] * 2).rename("c")
df = pd.concat([df,c], axis = 1)
df
   a  b  c
0  1  4  2
1  2  5  4
2  3  6  6

使用join

df.join(c)
   a  b  c
0  1  4  2
1  2  5  4
2  3  6  6

3 个答案:

答案 0 :(得分:3)

一种简洁的方法是:

df['c'] = 2 * df['a']

无需逐元素计算新列。

答案 1 :(得分:3)

简短的回答:矢量化调用(df['c'] = 2 * df['a'])几乎总是在速度和可读性上取胜。有关在性能方面可以用作选项的“层次结构”的信息,请参见this答案。


通常,如果您在Pandas操作的某处存在for i in ...lambda,这(有时)意味着结果计算将调用 Python 代码,而不是熊猫的Cython库用于矢量化操作的优化C代码。 (对于依赖于基础.values的NumPy函数的操作也是如此。)

对于.assign(),在注释中正确指出这会创建一个副本,而您可以将df['c'] = 2 * df['a']视为设置字典键/值的等效项。前者的时间也要花两倍的时间,尽管这可能有点麻烦,因为一个操作返回一个DataFrame,而另一个操作只是分配一个列。

>>> %timeit df.assign(c=df['a'] * 2)
498 µs ± 15.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

>>> %timeit -r 7 -n 1000 df['c'] = df['a'] * 2
239 µs ± 22.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

对于.map():顾名思义,通常当您想为Series提供 mapping 时(虽然可以像在您的代码中那样传递函数),您会看到此信息题)。这并不意味着它不是高性能的,只是在我见过的情况下它往往被用作一种专门的方法:

>>> df['a'].map(dict(enumerate('xyz', 1)))
0    x
1    y
2    z
Name: a, dtype: object

对于.apply():要在答案中注入一点意见,我认为在可能的情况下使用向量化会更加惯用。您可以在module where .apply() is defined的代码中看到:由于您传递的是lambda而不是NumPy ufunc,因此最终被称为的是Cython函数map_infer,但它仍然可以执行您所需要的任何功能一次传给df['a']系列的每个成员。

答案 2 :(得分:0)

为什么要使用lambda函数? 您可以通过

轻松地完成上述任务
df['c'] = 2 * df['a']

这不会增加开销。