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
是否有更多的矢量化,但它的操作范围要小得多。