熊猫:根据条件将数据框中的值复制到多行

时间:2019-01-27 12:38:50

标签: python pandas

我需要分析熊猫数据框中的价格序列,以查看是否出现了两个连续的较低低点,从而创建了我们称为NLBL的价格水平。我可以使用简单的条件条件(请参见下文)来执行此操作,但我需要的是前三个蜡烛高的值,而不是TRUE值。另外,我需要将该相同级别的副本再复制四次。

这是一些示例数据:

        Date      Time     Open     High      Low    Close
datetime                                                                     
2019-01-22 11:00:00  2019-01-22  11:00:00  2643.99  2647.47  2634.73  2634.73
2019-01-22 12:00:00  2019-01-22  12:00:00  2634.79  2638.55  2632.69  2635.94
2019-01-22 13:00:00  2019-01-22  13:00:00  2635.95  2636.35  2623.30  2631.93
2019-01-22 14:00:00  2019-01-22  14:00:00  2631.92  2632.29  2618.33  2622.66
2019-01-22 15:00:00  2019-01-22  15:00:00  2622.71  2632.90  2617.27  2625.49
2019-01-22 16:00:00  2019-01-22  16:00:00  2625.58  2633.81  2625.58  2633.81
2019-01-23 09:00:00  2019-01-23  09:00:00  2643.48  2652.44  2643.48  2650.97
2019-01-23 10:00:00  2019-01-23  10:00:00  2651.00  2653.19  2632.85  2634.47
2019-01-23 11:00:00  2019-01-23  11:00:00  2634.47  2638.55  2617.36  2617.46
2019-01-23 12:00:00  2019-01-23  12:00:00  2617.47  2627.43  2612.86  2627.31
2019-01-23 13:00:00  2019-01-23  13:00:00  2627.31  2631.70  2621.62  2629.92
2019-01-23 14:00:00  2019-01-23  14:00:00  2629.93  2635.26  2625.34  2629.21
2019-01-23 15:00:00  2019-01-23  15:00:00  2629.25  2639.22  2628.71  2636.61
2019-01-23 16:00:00  2019-01-23  16:00:00  2636.71  2639.54  2636.71  2638.60
2019-01-24 09:00:00  2019-01-24  09:00:00  2638.84  2641.03  2631.06  2636.14
2019-01-24 10:00:00  2019-01-24  10:00:00  2636.18  2647.20  2633.12  2640.49
2019-01-24 11:00:00  2019-01-24  11:00:00  2640.31  2645.37  2633.60  2644.08
2019-01-24 12:00:00  2019-01-24  12:00:00  2644.14  2644.42  2632.79  2634.31
2019-01-24 13:00:00  2019-01-24  13:00:00  2634.34  2635.16  2627.01  2633.62
2019-01-24 14:00:00  2019-01-24  14:00:00  2633.64  2638.47  2630.96  2637.04
2019-01-24 15:00:00  2019-01-24  15:00:00  2637.03  2643.21  2636.46  2642.66
2019-01-24 16:00:00  2019-01-24  16:00:00  2642.63  2643.10  2641.97  2641.99
2019-01-25 09:00:00  2019-01-25  09:00:00  2657.44  2663.57  2657.33  2661.64
2019-01-25 10:00:00  2019-01-25  10:00:00  2661.60  2671.61  2661.60  2669.49
2019-01-25 11:00:00  2019-01-25  11:00:00  2669.47  2670.50  2664.18  2669.13
2019-01-25 12:00:00  2019-01-25  12:00:00  2669.12  2672.38  2661.39  2664.88
2019-01-25 13:00:00  2019-01-25  13:00:00  2664.88  2668.49  2663.76  2667.93
2019-01-25 14:00:00  2019-01-25  14:00:00  2667.95  2669.12  2661.14  2665.27
2019-01-25 15:00:00  2019-01-25  15:00:00  2665.27  2666.52  2658.75  2663.06
2019-01-25 16:00:00  2019-01-25  16:00:00  2662.98  2664.74  2661.64  2664.14

这是我到目前为止所走的距离:

min_data['NLBL'] = (min_data['Low'] < min_data['Low'].shift(1)) & (min_data['Low'].shift(1) < min_data['Low'].shift(2))
min_data['NLBL'] = min_data['NLBL'].shift(periods=1) # shifting downward as the trigger is valid after the close
print("\nResult:\n %s" % min_data.tail(30))

Result:
            Date      Time     Open     High      Low    Close  \
datetime                                                                        
2019-01-22 11:00:00  2019-01-22  11:00:00  2643.99  2647.47  2634.73  2634.73   
2019-01-22 12:00:00  2019-01-22  12:00:00  2634.79  2638.55  2632.69  2635.94   
2019-01-22 13:00:00  2019-01-22  13:00:00  2635.95  2636.35  2623.30  2631.93   
2019-01-22 14:00:00  2019-01-22  14:00:00  2631.92  2632.29  2618.33  2622.66   
2019-01-22 15:00:00  2019-01-22  15:00:00  2622.71  2632.90  2617.27  2625.49   
2019-01-22 16:00:00  2019-01-22  16:00:00  2625.58  2633.81  2625.58  2633.81   
2019-01-23 09:00:00  2019-01-23  09:00:00  2643.48  2652.44  2643.48  2650.97   
2019-01-23 10:00:00  2019-01-23  10:00:00  2651.00  2653.19  2632.85  2634.47   
2019-01-23 11:00:00  2019-01-23  11:00:00  2634.47  2638.55  2617.36  2617.46   
2019-01-23 12:00:00  2019-01-23  12:00:00  2617.47  2627.43  2612.86  2627.31   
2019-01-23 13:00:00  2019-01-23  13:00:00  2627.31  2631.70  2621.62  2629.92   
2019-01-23 14:00:00  2019-01-23  14:00:00  2629.93  2635.26  2625.34  2629.21   
2019-01-23 15:00:00  2019-01-23  15:00:00  2629.25  2639.22  2628.71  2636.61   
2019-01-23 16:00:00  2019-01-23  16:00:00  2636.71  2639.54  2636.71  2638.60   
2019-01-24 09:00:00  2019-01-24  09:00:00  2638.84  2641.03  2631.06  2636.14   
2019-01-24 10:00:00  2019-01-24  10:00:00  2636.18  2647.20  2633.12  2640.49   
2019-01-24 11:00:00  2019-01-24  11:00:00  2640.31  2645.37  2633.60  2644.08   
2019-01-24 12:00:00  2019-01-24  12:00:00  2644.14  2644.42  2632.79  2634.31   
2019-01-24 13:00:00  2019-01-24  13:00:00  2634.34  2635.16  2627.01  2633.62   
2019-01-24 14:00:00  2019-01-24  14:00:00  2633.64  2638.47  2630.96  2637.04   
2019-01-24 15:00:00  2019-01-24  15:00:00  2637.03  2643.21  2636.46  2642.66   
2019-01-24 16:00:00  2019-01-24  16:00:00  2642.63  2643.10  2641.97  2641.99   
2019-01-25 09:00:00  2019-01-25  09:00:00  2657.44  2663.57  2657.33  2661.64   
2019-01-25 10:00:00  2019-01-25  10:00:00  2661.60  2671.61  2661.60  2669.49   
2019-01-25 11:00:00  2019-01-25  11:00:00  2669.47  2670.50  2664.18  2669.13   
2019-01-25 12:00:00  2019-01-25  12:00:00  2669.12  2672.38  2661.39  2664.88   
2019-01-25 13:00:00  2019-01-25  13:00:00  2664.88  2668.49  2663.76  2667.93   
2019-01-25 14:00:00  2019-01-25  14:00:00  2667.95  2669.12  2661.14  2665.27   
2019-01-25 15:00:00  2019-01-25  15:00:00  2665.27  2666.52  2658.75  2663.06   
2019-01-25 16:00:00  2019-01-25  16:00:00  2662.98  2664.74  2661.64  2664.14   

          NLBL  
datetime                    
2019-01-22 11:00:00   True  
2019-01-22 12:00:00   True  
2019-01-22 13:00:00   True  
2019-01-22 14:00:00   True  
2019-01-22 15:00:00   True  
2019-01-22 16:00:00   True  
2019-01-23 09:00:00  False  
2019-01-23 10:00:00  False  
2019-01-23 11:00:00  False  
2019-01-23 12:00:00   True  
2019-01-23 13:00:00   True  
2019-01-23 14:00:00  False  
2019-01-23 15:00:00  False  
2019-01-23 16:00:00  False  
2019-01-24 09:00:00  False  
2019-01-24 10:00:00  False  
2019-01-24 11:00:00  False  
2019-01-24 12:00:00  False  
2019-01-24 13:00:00  False  
2019-01-24 14:00:00   True  
2019-01-24 15:00:00  False  
2019-01-24 16:00:00  False  
2019-01-25 09:00:00  False  
2019-01-25 10:00:00  False  
2019-01-25 11:00:00  False  
2019-01-25 12:00:00  False  
2019-01-25 13:00:00  False  
2019-01-25 14:00:00  False  
2019-01-25 15:00:00  False  
2019-01-25 16:00:00   True

这就是我被困的地方。我需要从这里做两件事:

  1. True中的每个min_value['NLBL']替换为Hight.Shift(3)-本质上是该系列中的最高最低价。还将每个False设置为0。

  2. 将没有填充0的每一行min_value['NLBL']复制四次,直到找到下一个0。

我认为用lambda表达式是合适的,但是在熊猫的背景下进行所有这些操作却使我感到困惑。有什么想法/见解如何在不求助于缓慢/丑陋/烦人的if循环的情况下做到这一点?

这只是我将要实现的几种类似模式的一个示例。因此解决这个问题对我来说是个大问题,任何帮助将不胜感激。

谢谢!

更新:有人要求NLBL列的正确输出:

          NLBL  
datetime                    
2019-01-22 14:00:00  2647.47  
2019-01-22 15:00:00  2638.55  
2019-01-22 16:00:00  2636.35  
2019-01-23 09:00:00  0  
2019-01-23 10:00:00  0  
2019-01-23 11:00:00  0  
2019-01-23 12:00:00  2652.44 
2019-01-23 13:00:00  2653.19  
2019-01-23 14:00:00  2653.19   
2019-01-23 15:00:00  2653.19   
2019-01-23 16:00:00  2653.19   
2019-01-24 09:00:00  2653.19   
2019-01-24 10:00:00  0  
2019-01-24 11:00:00  0  
2019-01-24 12:00:00  0  
2019-01-24 13:00:00  0  
2019-01-24 14:00:00  2645.37 
2019-01-24 15:00:00  2645.37 
2019-01-24 16:00:00  2645.37 
2019-01-25 09:00:00  2645.37 
2019-01-25 10:00:00  2645.37  
2019-01-25 11:00:00  0  
2019-01-25 12:00:00  0  
2019-01-25 13:00:00  0  
2019-01-25 14:00:00  0  
2019-01-25 15:00:00  0  
2019-01-25 16:00:00  2668.49

如果到达“ NLBL”列中具有TRUE值的行,它将向后计数三行,抓取“ High”值并将TRUE替换为该行。然后将相同的“高”值复制到以下四行。

但是,如果找到新的TRUE,它将停止向前复制并使用新的High值。

希望这很有道理。

1 个答案:

答案 0 :(得分:1)

感谢您的澄清,非常确定我理解您(尽管如果我理解正确,那么示例输出中会有一个小错误)。

这是我的解决方案:基本上添加一个辅助列,将0替换为NaN(如果您对性能有严重的担忧,可以考虑使用map而不是replace),并使用两个fillna个方法:

min_data['helper'] = min_data['High'].shift(3)
min_data.loc[min_data['NLBL'] == True, 'NLBL'] = min_data.loc[min_data['NLBL'] == True, 'helper']
min_data = min_data.drop(columns=['helper'])
min_data.NLBL = min_data.NLBL.replace(False, np.nan)
min_data['NLBL'] = min_data['NLBL'].fillna(method='ffill', limit=4)
min_data['NLBL'] = min_data['NLBL'].fillna(0)