Python 滚动求和然后使用此滚动求和得到随机整数
我有这个数据框:Python 滚动求和然后使用此滚动求和得到随机整数,python,pandas,Python,Pandas,我有这个数据框: Date A 0 2014-11-21 11:00:00 1 1 2014-11-21 11:00:03 2 2 2014-11-21 11:00:04 5 3 2014-11-21 11:00:05 3 4 2014-11-21 11:00:07 9 5 2014-11-21 11:00:08 6 6 2014-11-21 11:00:10 3 7 2014-11-21 11:00:11 1 8 201
Date A
0 2014-11-21 11:00:00 1
1 2014-11-21 11:00:03 2
2 2014-11-21 11:00:04 5
3 2014-11-21 11:00:05 3
4 2014-11-21 11:00:07 9
5 2014-11-21 11:00:08 6
6 2014-11-21 11:00:10 3
7 2014-11-21 11:00:11 1
8 2014-10-24 10:00:55 8
9 2014-10-24 10:00:59 10
我试图计算一列a
的滚动和,周期为2秒
假设这个新列名为rsum
在计算了rsum'列之后,我想用它来创建另一个名为
B`的列
B
值是A
值+介于-1*rsum和rsum之间的随机整数
以下是我的完整工作代码:
import pandas as pd
import numpy as np
from datetime import timedelta
from random import seed, randrange
df = pd.DataFrame({"Date": ['2014-11-21 11:00:00', '2014-11-21 11:00:03', '2014-11-21 11:00:04', '2014-11-21 11:00:05', '2014-11-21 11:00:07', '2014-11-21 11:00:08', '2014-11-21 11:00:10', '2014-11-21 11:00:11', '2014-10-24 10:00:55', '2014-10-24 10:00:59'], "A":[1, 2, 5, 3, 9, 6, 3,1, 8, 10]})
df
df.Date=pd.to_datetime(df.Date)
df['ind']=df.index
df = df.set_index('Date')
df['rsum']= df.groupby('ind').rolling('2s', closed = 'both').A.sum().reset_index(level=0, drop=True)
df['B'] = df.apply(lambda x : randrange(-x.rsum, x.rsum), axis=1)
print(df.drop(columns=['ind', 'rsum']).reset_index())
结果是:
Date A B
0 2014-11-21 11:00:00 1 0
1 2014-11-21 11:00:03 2 1
2 2014-11-21 11:00:04 5 -5
3 2014-11-21 11:00:05 3 1
4 2014-11-21 11:00:07 9 6
5 2014-11-21 11:00:08 6 2
6 2014-11-21 11:00:10 3 2
7 2014-11-21 11:00:11 1 0
8 2014-10-24 10:00:55 8 0
9 2014-10-24 10:00:59 10 -2
我的代码实际上正在工作,但我对Python还是新手,我确信这不是实现这一点的最有效的方法。因为计算B值不是矢量化的'df['B']=df.apply(lambda x:randrange(-x.rsum,x.rsum),axis=1)
我还有另一个问题,如果我必须对多个列执行此操作,而不是仅对一个列执行此操作,我认为最明显的方法是对每个列执行for循环,并重复df['B']=df.apply(lambda x:randrange(-x.rsum,x.rsum),axis=1)。
实现这一点最有效的方法是什么?我使用
numpy
和randrange
对4种方法进行了基准测试
%timeit df['B'] = df.apply(lambda x : randrange(-x.rsum, x.rsum), axis=1)
2.06 ms ± 44.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit df['C'] = df.apply(lambda x : np.random.randint(-x.rsum, x.rsum), axis=1)
2.07 ms ± 34.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit df['D'] = df['rsum'].map(lambda x : np.random.randint(-x, x))
340 µs ± 2.39 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
# Winner
%timeit df['E'] = df['rsum'].map(lambda x : randrange(-x, x))
333 µs ± 3.59 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
正如您可以看到的那样,
randrange
with map是最快的
,如果操作只在一列上,您不应该使用apply
,最新的numpy
开发者版本可以开箱即用,但由于您可能没有这个功能,您需要的是一个矢量化版本的np.random.randint
:
>>> def randint(x):
... return np.random.randint(-x, x)
...
>>> np.vectorize(randint)(df.rsum)
array([ 0, 0, -1, -3, -1, 5, 2, 0, -8, 4])
在应用之前,一切都是一样的。你可以把它放在一个新的专栏里,以此类推。您也可以删除rsum
,只需使用前面的命令输出即可。确保在实际代码中只矢量化一次,以便
my_rand = np.vectorize(randint)
df['new_col'] = my_rand(df.rsum)
总的来说,熊猫和努比玩得很好。在使用这些库时,我不会使用非Numpy(或Scipy)提供的
random
内容。好的,谢谢。那多列的情况呢?我能用什么技巧来表达这个观点吗?有很多变量需要考虑,而且很有情境性;然而,对于基本的数学运算,对多列使用apply
你的意思是map
?map
->单列,apply
->多列,换句话说apply
是针对数据帧的。我不确定map
是否有更多的矢量化,但它的操作范围要小得多。