【问题标题】:Limiting the calculation in a column when it reaches a certain value and restarting it again when specific conditions are met当某列达到一定值时限制计算,满足特定条件时重新开始计算
【发布时间】:2025-12-28 10:35:06
【问题描述】:

这几天我一直在努力对列进行一些修改。batt_status 列的计算如下:

如果 (batt_input) > 0:
batt_status[i] = batt_status[i-1] + (batt_input[i] / 4)
其他:
batt_status[i] = batt_status[i-1] - (batt_output[i] / 4)。

   batt_input   batt_output batt_status
0   0.000000    0.000000    0.000000
1   2.739314    0.000000    0.684829
2   5.000000    0.000000    1.934829
3   5.000000    0.000000    3.184829
4   4.190054    0.000000    4.232342
5   4.627677    0.000000    5.389261
6   4.237302    0.000000    6.448587
7   1.251996    0.000000    6.761586
8   4.147673    0.000000    7.798504
9   2.921009    0.000000    8.528756
10  4.877213    0.000000    9.748060
11  5.000000    0.000000    10.998060
12  5.000000    0.000000    12.248060
13  5.000000    0.000000    13.498060
14  0.000000    3.120185    12.718013
15  0.000000    3.094523    11.944382
16  0.000000    3.711843    11.016422
17  0.000000    4.338085    9.931900
18  0.000000    4.173286    8.888579
19  0.000000    4.312411    7.810476
20  0.000000    4.345891    6.724003
21  0.000000    4.512739    5.595818
22  0.000000    4.543866    4.459852
23  0.000000    4.450718    3.347172
24  0.000000    4.511852    2.219209
25  0.000000    4.765721    1.027779
26  0.000000    4.713985    -0.150717
27  0.000000    4.604684    -1.301888

我用过代码:

df['batt_status'] =  np.where(df['batt_input'] == 0, 0, np.nan)

for i in range(1, len(df)):
    if(df.loc[i, 'batt_input'] > 0):
        df.loc[i, 'batt_status'] = df.loc[i-1, 'batt_status'] + (df.loc[i, 'batt_input']/4)
    else:
        df.loc[i, 'batt_status'] = df.loc[i-1, 'batt_status'] - (df.loc[i, 'batt_output']/4)       

正如您在batt_status 列中所指出的,可能会累积负值或强正值。现在我想限制batt_status列中的值,使它们达到最小值0和最大值20。

然后,当达到零时,后续值应该重复零,直到可以添加其他值(batt_input > 0)。

一旦达到值 20,它也应该被复制,直到可以减去一些东西 (batt_output > 0)。以此类推。

预期输出(示例):

    batt_input  batt_output batt_status
0   0.000000    0.000000    0.000000
1   2.739314    0.000000    0.684829
2   5.000000    0.000000    1.934829
3   5.000000    0.000000    3.184829
4   4.190054    0.000000    4.232342
5   4.627677    0.000000    5.389261
6   4.237302    0.000000    6.448587
7   1.251996    0.000000    6.761586
8   4.147673    0.000000    7.798504
9   2.921009    0.000000    8.528756
10  4.877213    0.000000    9.748060
11  5.000000    0.000000    10.998060
12  5.000000    0.000000    12.248060
13  5.000000    0.000000    13.498060
14  0.000000    3.120185    12.718013
15  0.000000    3.094523    11.944382
16  0.000000    3.711843    11.016422
17  0.000000    4.338085    9.931900
18  0.000000    4.173286    8.888579
19  0.000000    4.312411    7.810476
20  0.000000    4.345891    6.724003
21  0.000000    4.512739    5.595818
22  0.000000    4.543866    4.459852
23  0.000000    4.450718    3.347172
24  0.000000    4.511852    2.219209
25  0.000000    4.765721    1.027779
26  0.000000    4.713985    0.000000 # (here batt_status reaches lower than 0, so put the smallest possible i.e. 0)
27  0.000000    4.604684    0.000000 # repeat 0
28  0.000000    3.567943    0.000000 # repeat 0 
29  0.000000    2.344556    0.000000 # repeat 0
30  2.739314    0.000000    0.684829 # can add (batt_input/4)
31  10.35678    0.000000    3.274024
32  65.03452    0.000000    19.53265
33  3.452341    0.000000    20.00000 # (here batt_status reaches value greater than 20, so put as much as possible, i.e. 20)
34  2.345566    0.000000    20.00000 # repeat 20
35  45.56677    0.000000    20.00000 # repeat 20 
36  0.000000    25.45600    13.63600 # can substract (batt_output/4) 
37  0.000000    2.445552    13.02462 

你对此有什么想法吗?

【问题讨论】:

  • 你能以reproducible的方式提供你的数据集吗?
  • @sophcles 刚刚添加,希望对您有所帮助
  • 谢谢,不过还是不太理想。请问您也可以添加您想要的输出吗?
  • 对不起,我忘记了最重要的事情在我的脑海中。我添加了预期的输出

标签: python pandas dataframe loops


【解决方案1】:

使用minmax 修改代码相当容易;下面的实现加上一个小改动

df['batt_change'] = np.where(df['batt_input']>0, df['batt_input']/4, -df['batt_output']/4)

df['batt_status'] = 0
for i in range(1, len(df)):
    df.loc[i, 'batt_status']  = min(max(df.loc[i-1, 'batt_status'] + df.loc[i, 'batt_change'],0),20)

引入'batt_change' 列的原因是您的原始代码可以简单地实现

df['batt_status'] = df['batt_change'].cumsum()

但很遗憾,我们不能这样做,因为您想限制和限制输出。所以还是需要那个循环

df 看起来像这样(对于您的第二个示例)

      batt_input    batt_output    batt_change    batt_status
--  ------------  -------------  -------------  -------------
 0       0              0            -0              0
 1       2.73931        0             0.684828       0.684828
 2       5              0             1.25           1.93483
 3       5              0             1.25           3.18483
 4       4.19005        0             1.04751        4.23234
 5       4.62768        0             1.15692        5.38926
 6       4.2373         0             1.05933        6.44859
 7       1.252          0             0.312999       6.76159
 8       4.14767        0             1.03692        7.7985
 9       2.92101        0             0.730252       8.52876
10       4.87721        0             1.2193         9.74806
11       5              0             1.25          10.9981
12       5              0             1.25          12.2481
13       5              0             1.25          13.4981
14       0              3.12019      -0.780046      12.718
15       0              3.09452      -0.773631      11.9444
16       0              3.71184      -0.927961      11.0164
17       0              4.33809      -1.08452        9.9319
18       0              4.17329      -1.04332        8.88858
19       0              4.31241      -1.0781         7.81048
20       0              4.34589      -1.08647        6.724
21       0              4.51274      -1.12818        5.59582
22       0              4.54387      -1.13597        4.45985
23       0              4.45072      -1.11268        3.34717
24       0              4.51185      -1.12796        2.21921
25       0              4.76572      -1.19143        1.02778
26       0              4.71399      -1.1785         0
27       0              4.60468      -1.15117        0
28       0              3.56794      -0.891986       0
29       0              2.34456      -0.586139       0
30       2.73931        0             0.684828       0.684828
31      10.3568         0             2.5892         3.27402
32      65.0345         0            16.2586        19.5327
33       3.45234        0             0.863085      20
34       2.34557        0             0.586391      20
35      45.5668         0            11.3917        20
36       0             25.456        -6.364         13.636
37       0              2.44555      -0.611388      13.0246

【讨论】:

  • 很好......你救了我的命,它有效