如何获取当前循环的前一个值和后一个值?

-1 投票
5 回答
55 浏览
提问于 2025-04-14 15:45

我正在做一个热指数计算的项目,项目会从文件 Temperature365.txt 和 Humidity365.txt 中读取温度和湿度的值。如果遇到值为 0 的情况,我希望能用它前面的值和后面的值的平均数来替代这个 0。

举个例子,比如有以下的数值:

34
21
0
42

我希望用 (21+42)/2 来替代 0,而不是用 (21+34)/2。请问我该如何修改这段代码呢?

c1 = -8.78469475556
c2 = 1.61139411
c3 = 2.33854883889
c4 = -0.14611605
c5 = -0.012308094
c6 = -0.0164248277778
c7 = 2.211732 * 10**-3
c8 = 7.2546 * 10**-4
c9 = -3.582 * 10**-6

def whatstatus(hi_val):
    if hi_val >= 54:
        return "Extreme Danger"
    elif 41 <= hi_val < 54:
        return "Danger"
    elif 32 <= hi_val < 41:
        return "Extreme Caution"
    elif 27 <= hi_val < 32:
        return "Caution"
    else:
        return "Normal"

def cal_hi(T, H):
    Hi = c1 + (c2 * T) + (c3 * H) + (c4 * T * H) + (c5 * (T**2)) + (c6 * (H**2)) + (c7 * (T**2) * H) + (c8 * T * (H**2)) + (c9 * (T**2) * (H**2))
    return Hi

def handle_missing_values(data_list):
    """Fills missing values in a list using the average of the previous and next values (if available)."""
    if len(data_list) <= 1:
        return data_list  # Handle edge cases with 0 or 1 elements

    output_list = []
    for i in range(len(data_list)):
        if data_list[i] != 0:
            output_list.append(data_list[i])
        else:
            prev_value = data_list[max(i - 1, 0)]  # Safeguard against negative index
            next_value = data_list[min(i + 1, len(data_list) - 1)]  # Safeguard against exceeding list bounds
            if prev_value != 0 and next_value != 0:  # Check if both neighbors are valid
                output_list.append((prev_value + next_value) / 2)
            else:
                # Handle cases where only one neighbor is valid (or none)
                output_list.append(data_list[i])  # Maintain original value (0)

    return output_list

with open('Humidity365.txt') as Hf, open('Temperature365.txt') as Tf:
    print("Day\tTemperature(C)\tHumidity(%)\tHeat Index\tStatus", "\n", "---" * 22)

    Tlist = []
    Hlist = []

    for i, (Tl, Hl) in enumerate(zip(Tf, Hf)):
        Tx = float(Tl.strip())
        Hx = float(Hl.strip())

        # Specific fix for line 12 (index 11) using list comprehension
        if Hx == 0:  # Check for 0 value specifically at index 11
            prev_Hx = Hlist[i - 1]
            next_Hx = Hlist[i + 1]
            Hx = (prev_Hx + next_Hx) / 2  # Calculate average for line 12 only
        elif Hx == 0:  # Apply the 0-replacement rule to other lines
            Hx = handle_missing_values([Hx])[0]

        Tlist.append(Tx)
        Hlist.append(Hx)

        heat_index_val = cal_hi(Tx, Hx)
        stat = whatstatus(heat_index_val)
        print(f"{i+1}\t{Tx:.2f}\t\t{Hx:.2f}\t\t{heat_index_val:.2f}\t\t{stat}")

        if len(Tlist) % 30 == 0:
            input("Press <ENTER> to continue")

我希望每次遇到 0 的时候,都能用 (前一个值 + 后一个值) / 2 来替代它。

5 个回答

0

你可以使用enumerate()和列表推导式。假设你列表中的第一个和最后一个元素都不是0,下面的代码应该可以正常工作:

def handle_missing_values(dl):
    return [i if i != 0 else (dl[j-1]+dl[j+1])/2 for j,i in enumerate(dl)]
0

你需要把代码拆分开来,并且需要用到两个循环。

  • 第一个循环是从文件中读取每一行,创建 HlistTlist
  • 然后调用 handle_missing_values 函数两次,来清理 HlistTlist 中的数据。
  • 第二个循环用来进行计算,计算 heat_index_valstat,这次是遍历 HlistTlist

另外,因为你的 handle_missing_values 函数已经考虑到了特殊情况,所以你不需要再做特别的修复了。

我建议在处理无效值时,可以使用全局平均值或者最近邻的值。如果邻居的值都无效,那就直接把0值去掉再进行后续处理。不过这要看你的具体需求。

顺便提一下,你的 ifelif 条件是一样的,对于所有 Hx==0 的情况,代码会尝试访问 i-1i+1 的元素,但 i+1 还没有生成(如果 i=0 的话,i-1 也会出问题)。

0

你可以使用 itertools 来实现这个功能:

import itertools


data = [1, 2, 3, 4, 5, 6, 7]
prev_pool, current_pool, next_pool = itertools.tee(data, 3)
prev_pool = itertools.chain([-1], prev_pool)
next(next_pool)
next_pool = itertools.chain(next_pool, [-9])

for prev_element, current_element, next_element in zip(prev_pool, current_pool, next_pool):
    print(f"{prev_element=}, {current_element=}, {next_element=}")

输出结果:

prev_element=-1, current_element=1, next_element=2
prev_element=1, current_element=2, next_element=3
prev_element=2, current_element=3, next_element=4
prev_element=3, current_element=4, next_element=5
prev_element=4, current_element=5, next_element=6
prev_element=5, current_element=6, next_element=7
prev_element=6, current_element=7, next_element=-9

注意事项:

  • 我们使用 tee 来把列表分成三个可迭代的部分
  • 对于 previous_pool,我们在前面加上一个值 -1。这个值可以是任何对我们的计算方便的数字
  • 对于 next_pool,我们把池子往前移动,并在后面加上 -9。同样,这个值也可以是任何方便的数字
  • 之后,我们可以把这些池子合并在一起,然后逐个遍历它们

撰写回答