我正在使用pandas库,我想在数据框 df
中添加两个新列,其中包含n列(n> 0) .
这些新列是将函数应用于数据框中的一列的结果 .
应用的功能如下:
def calculate(x):
...operate...
return z, y
为仅返回值的函数创建新列的一种方法是:
df['new_col']) = df['column_A'].map(a_function)
所以,我想要的,并尝试不成功(*),是这样的:
(df['new_col_zetas'], df['new_col_ys']) = df['column_A'].map(calculate)
最好的方法是什么?我没有任何线索地扫描了documentation .
** df['column_A'].map(calculate)
返回一个pandas系列,每个项目由一个元组z,y组成 . 并尝试将其分配给两个dataframe列会产生ValueError . *
2 回答
我只是使用
zip
:在我看来,最重要的答案是有缺陷的 . 希望没有人用
from pandas import *
将所有pandas大量导入其命名空间 . 此外,map
方法应该在传递字典或系列时保留 . 它可以采用一个函数,但这是apply
用于 .所以,如果你必须使用上面的方法,我会这样写
实际上没有理由在这里使用zip . 你可以这样做:
第二种方法在较大的DataFrame上也快得多
DataFrame创建了300,000行
比拉链快60倍
一般情况下,避免使用申请
应用通常不比迭代Python列表快得多 . 让我们测试一个for循环的性能来做同样的事情
所以这是两倍慢,这不是一个糟糕的性能回归,但如果我们对上述进行cython化,我们会获得更好的性能 . 假设您正在使用ipython:
直接分配,无需申请
如果使用直接矢量化操作,则可以获得更大的速度提升 .
这利用了NumPy极快的矢量化操作而不是我们的循环 . 我们现在的速度比原版快了30倍 .
最简单的速度测试,适用
上面的例子应该清楚地显示出
apply
的速度有多慢,但正好让它更加清晰,让's look at the most basic example. Let' s方形成为1000万个数字的系列,有或没有适用没有申请是快50倍