假设我有一个以下形式的DataFrame,其中第一列是随机数,其他列将基于上一列中的值。
为了便于使用,假设我希望每个数字都是前一个数字。所以看起来如下所示。
我知道我可以写一个非常简单的循环来做这个,但我也知道循环在python / pandas中通常不是最有效的。如何使用apply()
或rolling_apply()
完成此操作?或者,否则更有效率地完成?
我的(失败)尝试如下:
In [12]: a = pandas.DataFrame({0:[1,2,3,4,5],1:0,2:0,3:0})
In [13]: a
Out[13]:
0 1 2 3
0 1 0 0 0
1 2 0 0 0
2 3 0 0 0
3 4 0 0 0
4 5 0 0 0
In [14]: a = a.apply(lambda x: x**2)
In [15]: a
Out[15]:
0 1 2 3
0 1 0 0 0
1 4 0 0 0
2 9 0 0 0
3 16 0 0 0
4 25 0 0 0
In [16]: a = pandas.DataFrame({0:[1,2,3,4,5],1:0,2:0,3:0})
In [17]: pandas.rolling_apply(a,1,lambda x: x**2)
C:\WinPython64bit\python-3.5.2.amd64\lib\site-packages\spyderlib\widgets\externalshell\start_ipython_kernel.py:1: FutureWarning: pd.rolling_apply is deprecated for DataFrame and will be removed in a future version, replace with
DataFrame.rolling(center=False,window=1).apply(args=<tuple>,kwargs=<dict>,func=<function>)
# -*- coding: utf-8 -*-
Out[17]:
0 1 2 3
0 1.0 0.0 0.0 0.0
1 4.0 0.0 0.0 0.0
2 9.0 0.0 0.0 0.0
3 16.0 0.0 0.0 0.0
4 25.0 0.0 0.0 0.0
In [18]: a = pandas.DataFrame({0:[1,2,3,4,5],1:0,2:0,3:0})
In [19]: a = a[:-1]**2
In [20]: a
Out[20]:
0 1 2 3
0 1 0 0 0
1 4 0 0 0
2 9 0 0 0
3 16 0 0 0
In [21]:
所以,我的问题主要是如何在我的DataFrame计算中引用前一个列值。
答案 0 :(得分:4)
您所描述的是递归关系,我认为目前没有任何非循环方式可以做到这一点。像apply
和rolling_apply
之类的东西仍然依赖于在开始之前获得所有需要的数据,并在结束时立即输出所有结果数据。也就是说,它们不允许您使用同一系列的早期值计算下一个值。请参阅this question和this one以及this pandas issue。
实际上,对于您的示例,您只需要填写三列,因此执行三遍循环(如其他一些答案中所示)可能不会成为主要的性能影响。
答案 1 :(得分:3)
a[1] = a[0].apply(lambda x: x**2)
a[2] = a[1].apply(lambda x: x**2)
a[3] = a[2].apply(lambda x: x**2)
会给你
0 1 2 3
0 1 1 1 1
1 2 4 16 256
2 3 9 81 6561
3 4 16 256 65536
4 5 25 625 390625
答案 2 :(得分:3)
不幸的是,据我所知,没有办法没有循环。但是,您不必遍历每个值,只需遍历每一列。您只需在上一列上调用apply并将下一列设置为返回值:
a = pd.DataFrame({0:[1,2,3,4,5],1:0,2:0,3:0})
for i in range(3):
a[i+1] = a[i].apply(lambda x: x**2)
答案 3 :(得分:3)
在这种特殊情况下,我们知道有关列的信息
Proposition
将成为0
1
将成为第1
栏中0
2
将成为2
列1
的强大功能......
2
列中0
4
将成为3
列2
的强大功能......
2
列中1
... 4
列中0
因此我们确实可以使用
对您的示例进行矢量化8
将其包装在漂亮的数据框中
np.power(df.values[:, [0]], np.power(2, np.arange(4)))
array([[ 1, 1, 1, 1],
[ 2, 4, 16, 256],
[ 3, 9, 81, 6561],
[ 4, 16, 256, 65536],
[ 5, 25, 625, 390625]])