Python 当前面的值很重要时,如何使用“apply()”或其他矢量化方法
假设我有一个如下形式的数据帧,其中第一列是一个随机数,其他列将基于前一列中的值 为了便于使用,假设我希望每个数字都是前一个数字的平方。所以它看起来像下图 我知道我可以编写一个非常简单的循环来实现这一点,但我也知道循环在python/pandas中通常不是最有效的。如何使用Python 当前面的值很重要时,如何使用“apply()”或其他矢量化方法,python,python-3.x,pandas,Python,Python 3.x,Pandas,假设我有一个如下形式的数据帧,其中第一列是一个随机数,其他列将基于前一列中的值 为了便于使用,假设我希望每个数字都是前一个数字的平方。所以它看起来像下图 我知道我可以编写一个非常简单的循环来实现这一点,但我也知道循环在python/pandas中通常不是最有效的。如何使用apply()或rolling\u apply()?或者,以其他方式可以更有效地完成 我的(失败)尝试如下: In [12]: a = pandas.DataFrame({0:[1,2,3,4,5],1:0,2:0,3:0}
apply()
或rolling\u 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]:
[12]中的a=pandas.DataFrame({0:[1,2,3,4,5],1:0,2:0,3:0})
在[13]中:a
出[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
在[14]中:a=a.apply(λx:x**2)
在[15]中:a
出[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
[16]中:a=pandas.DataFrame({0:[1,2,3,4,5],1:0,2:0,3:0})
在[17]中:熊猫。滚动应用(a,1,λx:x**2)
C:\WinPython64bit\python-3.5.2.amd64\lib\site packages\spyderlib\widgets\externalshell\start\u ipython\u kernel.py:1:FutureWarning:pd.rolling\u apply不推荐用于DataFrame,并将在将来的版本中删除,替换为
DataFrame.rolling(center=False,window=1).apply(args=,kwargs=,func=)
#-*-编码:utf-8-*-
出[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
[18]中:a=pandas.DataFrame({0:[1,2,3,4,5],1:0,2:0,3:0})
在[19]中:a=a[:-1]**2
在[20]中:a
出[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
在[21]中:
因此,我的问题主要是如何在数据帧计算中引用前面的列值
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
不幸的是,据我所知,没有一种没有循环的方法。但是,您不必遍历每个值,只需遍历每个列。您只需在上一列上调用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)
你所描述的是一个递归关系,我认为目前没有任何非循环的方法可以做到这一点。像
apply
和rolling\u apply
这样的事情仍然依赖于在开始之前获得所有需要的数据,并在结束时一次输出所有结果数据。也就是说,它们不允许您使用同一系列的早期值计算下一个值。见及
在实际操作中,例如,您只需要填写三列,因此执行三次循环(如其他一些答案所示)可能不会对性能造成重大影响。在这种特殊情况下,我们知道关于列的这一点
将成为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]])
将其包装在一个漂亮的数据框中
pd.DataFrame(
np.power(df.values[:, [0]], np.power(2, np.arange(4))),
df.index, df.columns)
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
a[1]=a[0]。应用(lambda x:x**2),非常感谢您的回复。我的实际数据帧要大得多,并且包含一些逻辑。这只是一个简单的例子,从效率的角度来学习如何最好地实现这一点。这些链接很有帮助。我真的很喜欢这种方法,这当然回答了我的问题。然而,我接受了另一个答案,因为我的问题是广义的。“我应该想到有一种更专业的方法来解决我的具体问题。”凯尔说了几点。第一:知道你可以接受另一个答案,如果你发现它比当前接受的答案更合适的话。事实上,这是受到鼓励的。我的回答中有不少没有被接受,我对此没有意见。第二:有时更难的问题需要更多的时间来回答。如果你想要一个有挑战性的问题的高质量答案,请耐心等待。没有必要急于接受答案。你也可以直截了当地回答那些已经回答了你正在等待的问题的人。第三:我不太关心15个代表分数,更关心什么是对的。@Kyle说了这么多。我完全同意凯尔的回答。其他人会根据自己的意愿投赞成票或反对票。:-)我喜欢这个。又好又简单。我上一次尝试使用完整循环(以及使用附加逻辑的完整数据源,并应用scipy.fv())花费了2分钟,这种方法花费了不到一秒钟的时间。我觉得自己很愚蠢:)。