Pandas DataFrame,计算相对于当前行列值的最大列值

时间:2017-07-16 15:01:29

标签: python pandas dataframe

我有一个数据框:

df = pd.DataFrame( {
    'epoch' : [1, 4, 7, 8, 9, 11, 12, 15, 16, 17], 
    'price' : [1, 2, 3, 3, 1, 4, 2, 3, 4, 4]
} )

   epoch  price
0      1      1
1      4      2
2      7      3
3      8      3
4      9      1
5     11      4
6     12      2
7     15      3
8     16      4
9     17      4

我必须创建一个新列,应按以下方式计算:

每行

查找当前行的时代(让我们说e_cur)

计算e_cur-3 = e_cur - 3(这里有三个常数,但它是可变的)

计算价格最大值,其中epoch> = e-3_cur和epoch< = e_cur

换句话说,在距离当前行的纪元三个时代的行中找到最高价格。

例如:

Index = 0,e_cur = epoch = 1,e_cur-3 = 1 -3 = -2,只有一个(第一)行,其epoch在-2和1之间,所以第一行的价格是最高价格

索引= 6,e_cur = epoch = 12,e_cur-3 = 12 - 3 = 9,有三行的历元在9到12之间,但索引= 5的行的最大价格= 4。

以下是我手动计算的每一行的结果:

   epoch  price  max_price_where_epoch_is_between_e_cur-3_and_e_cur
0      1      1                                                  1 
1      4      2                                                  2 
2      7      3                                                  3 
3      8      3                                                  3 
4      9      1                                                  3 
5     11      4                                                  4 
6     12      2                                                  4 
7     15      3                                                  3 
8     16      4                                                  4 
9     17      4                                                  4

正如你所看到的那样,时代的东西一个接一个地出现,但有时会出现'#34;漏洞"。

如何用熊猫计算?

3 个答案:

答案 0 :(得分:2)

考虑在epoch列上应用函数,您可以在其中找到所需的行并计算其price最大值

>> df['between'] = df['epoch'].apply(lambda e: df.loc[
>>                (df['epoch'] >= e - 3) & (df['epoch'] <= e), 'price'].max())
>> df
    epoch  price  between
 0      1      1        1
 1      4      2        2
 2      7      3        3
 3      8      3        3
 4      9      1        3
 5     11      4        4
 6     12      2        4
 7     15      3        3
 8     16      4        4
 9     17      4        4

答案 1 :(得分:2)

使用滚动窗口:

In [161]: df['between'] = df.epoch.map(df.set_index('epoch')
     ...:                                .reindex(np.arange(df.epoch.min(), df.epoch.max()+1))
     ...:                                .rolling(3, min_periods=1)
     ...:                                .max()['price'])
     ...:

In [162]: df
Out[162]:
   epoch  price  between
0      1      1      1.0
1      4      2      2.0
2      7      3      3.0
3      8      3      3.0
4      9      1      3.0
5     11      4      4.0
6     12      2      4.0
7     15      3      3.0
8     16      4      4.0
9     17      4      4.0

说明:

Helper DF:

In [165]: df.set_index('epoch').reindex(np.arange(df.epoch.min(), df.epoch.max()+1))
Out[165]:
       price
epoch
1        1.0
2        NaN
3        NaN
4        2.0
5        NaN
6        NaN
7        3.0
8        3.0
9        1.0
10       NaN
11       4.0
12       2.0
13       NaN
14       NaN
15       3.0
16       4.0
17       4.0

In [166]: df.set_index('epoch').reindex(np.arange(df.epoch.min(), df.epoch.max()+1)).rolling(3, min_periods=1).max()
Out[166]:
       price
epoch
1        1.0
2        1.0
3        1.0
4        2.0
5        2.0
6        2.0
7        3.0
8        3.0
9        3.0
10       3.0
11       4.0
12       4.0
13       4.0
14       2.0
15       3.0
16       4.0
17       4.0

答案 2 :(得分:0)

我尝试过两种解决方案,来自tarashypka和MaxU。 我尝试过的第一个解决方案是Tarashypka's。我测试了100k行。花了大约一分钟。

比我尝试过MaxU的解决方案,已经完成了大约4秒钟。

由于速度的原因,我更喜欢MaxU的解决方案,但是在Tarashypka的解决方案中,我还学会了如何在DataFrame中使用lambda函数。

非常感谢你们所有人。

最诚挚的问候和祝愿。