Python - 在迭代过程中锁定值

Python - Lock values in iteration process

我声明我不是 pytho 专家。通过这个 post 我想了解如何在上述过程中使用锁定值迭代过程(例如:for 循环)。

我将逐步解释我要查找的内容。 一开始我建立了一个数据框。

import pandas as pd

# Build the Dataframe

data = {'Col_1' : pd.Series(list(range(10,53,3))),
   'Col_2' : pd.Series(list(range(30,45))),
   'Col_3' : pd.Series([0,0,1,0,0,-1,0,0,1,0,0,0,-1,0,0])}

data = pd.DataFrame(data)
data['Result'] = 0
data['Result_1'] = 0

# Define a constant

c = 2

下面是上面代码的结果。

    Col_1  Col_2  Col_3  Result  Result_1
0      10     30      0       0         0
1      13     31      0       0         0
2      16     32      1       0         0
3      19     33      0       0         0
4      22     34      0       0         0
5      25     35     -1       0         0
6      28     36      0       0         0
7      31     37      0       0         0
8      34     38      1       0         0
9      37     39      0       0         0
10     40     40      0       0         0
11     43     41      0       0         0
12     46     42     -1       0         0
13     49     43      0       0         0
14     52     44      0       0         0

话虽如此,我想创建一个满足以下条件的迭代过程(例如:for 循环):

  1. if Col_3 = 1 锁定Col_1中的值,最后用这个在Col_2中执行操作,直到Col_3中的值变为等于-1,将结果放入'Result'列。

  2. if Col_3 = -1 使用前一点的锁定值,执行“前一点”的相同操作,另外将获得的结果乘以定义的常量 'c'。将结果放入 'Result_1' 列。

  3. 否则将 0 值放入两列('Result' 和 'Result_1')。

下面显示了迭代过程必须如何工作。

    Col_1  Col_2  Col_3   Result   Result_1
0      10     30      0        0          0
1      13     31      0        0          0
2      16     32      1  (16-32)          0
3      19     33      0  (16-33)          0
4      22     34      0  (16-34)          0
5      25     35     -1        0  (16-35)*c
6      28     36      0        0          0
7      31     37      0        0          0
8      34     38      1  (34-38)          0
9      37     39      0  (34-39)          0
10     40     40      0  (34-40)          0
11     43     41      0  (34-41)          0
12     46     42     -1        0  (34-42)*c
13     49     43      0        0          0
14     52     44      0        0          0

下面显示了预期的数据帧。

    Col_1  Col_2  Col_3  Result  Result_1
0      10     30      0       0         0
1      13     31      0       0         0
2      16     32      1     -16         0
3      19     33      0     -17         0
4      22     34      0     -18         0
5      25     35     -1       0       -38
6      28     36      0       0         0
7      31     37      0       0         0
8      34     38      1      -4         0
9      37     39      0      -5         0
10     40     40      0      -6         0
11     43     41      0      -7         0
12     46     42     -1       0       -16
13     49     43      0       0         0
14     52     44      0       0         0

总而言之,我知道我可以以更简单的方式获得相同的结果,而无需使用迭代器,但在这种特定情况下,我正在寻找可以向我解释我如何完成到目前为止所解释的过程的人通过使用迭代器(迭代器可以是 for 循环、while 或其他)。

在此先感谢您的帮助!

一种方法是使用 for 循环遍历 data 的索引:

on = False  # Switch starts with off (= False)
for i in data.index:
    if on:
        if data.at[i, 'Col_3'] == -1:  # Check if -1 in Col_3 is reached
            on = False  # Switch off (= False)
            data.at[i, 'Result_1'] = c * (col_1 - data.at[i, 'Col_2'])
        else:
            data.at[i, 'Result'] = col_1 - data.at[i, 'Col_2']
    else:
        if data.at[i, 'Col_3'] == 1:  # Check if 1 in Col_3 is reached
            on = True  # Switch on (= True)
            col_1 = data.at[i, 'Col_1']  # Store value of Col_1 in this position
            data.at[i, 'Result'] = col_1 - data.at[i, 'Col_2']

变量 on 跟踪程序是否处于哪个“阶段”(在 Col_3 中是否在 1 和 -1 之间)。

while 迭代索引的版本:

iterator = iter(data.index)
while True:
    try:
        i = next(iterator)
    except StopIteration:
        break
    if data.at[i, 'Col_3'] == 1:  # Check for 1 in Col_3
        col_1 = data.at[i, 'Col_1']  # Store value of Col_1 in this position
        while data.at[i, 'Col_3'] != -1:
            data.at[i, 'Result'] = col_1 - data.at[i, 'Col_2']
            try:
                i = next(iterator)
            except StopIteration:
                break
        # Value -1 in Col_3 reached
        data.at[i, 'Result_1'] = c * (col_1 - data.at[i, 'Col_2'])

如果没有 for,则需要使用 next() 显式完成迭代。这是在 try-except 块内完成的,以捕获 StopIteration 异常,然后 break 退出循环。如果你想在不捕捉到它的情况下看到会发生什么,请尝试:

iterator = iter(data.index)
while True:
    next(iterator)

在这两个版本中,我都省略了第 3 步,因为零已经存在。

一般来说:for 循环是一个更“可控”的环境。 while 循环通常提供更大的灵活性,但需要显式迭代。

(还有其他遍历 DataFrame 的方法,例如 data.iterrows()data.itertuples()。)