【问题标题】:python3 how to create a list that checks empty values and takes the average of the adjacent values to replace the empty value?python3如何创建一个检查空值并取相邻值的平均值来替换空值的列表?
【发布时间】:2020-07-26 00:18:29
【问题描述】:

我想创建一个提供输出的列表,如果原始列表有一个空值,它将取相邻值的总和平均值来替换它。假设缺失数据用-99表示

def clean_missing_data():
    
    data_list = []
    
    for number, adjacent in enumerate(a):
        
        if (number != -99):

            data_list.append(number)
            
        else:
            
            adjacent_left = a[number-1]
            adjacent_right = a[number+1]
            fill_in = (adjacent_left + adjacent_right) / 2    
            data_list.append(fill_in)
    
    return data_list

a = [1,2,3,-99,5]

check_data = clean_missing_data()

print('original test case:', a)
print('After clearing, the test case became:', check_data)

输出

original test case: [1, 2, 3, -99, 5]
After clearing, the test case became: [0, 1, 2, 3, 4]

例如对于这个测试用例,缺失值是列表的第四个数字(用-99表示),这意味着列表取相邻数据的总和平均值;值 3 和 5,并将其替换回列表。

本质上就是:[1,2,3, (3+5)/2, 5]

请帮忙!

【问题讨论】:

  • 你不要试图做你需要做的事情。你有什么问题?
  • 嗨帕特里克!我只对列表进行了过滤,如果列表包含 -99,它只返回一个不包括 -99 值的新列表。我无法做的是取平均相邻值(在本例中为值 3 和 5)并将其替换回列表。
  • 有很多极端情况需要考虑。如果列表的前 2 个元素是 -99 怎么办?或者如果列表中间有一串连续的 3 个 -99 值怎么办?等
  • @DV82XL 您好,只有当且仅当相邻价格是有效数据时,我们才能用平均值替换缺失的价格。如果我们无法计算平均价格,则缺失的价格将替换为具有有效值的相邻价格。所以我猜如果所有 5 个值都连续 -99,那么可能会返回一个简单的打印指示无法计算
  • 如果您的输入列表是 [-99, -99, 3, 4, 5] 怎么办?你的预期输出是什么? [1, -99, -99, -99, 5] 的输入呢?

标签: python-3.x list filter missing-data


【解决方案1】:

要求有点不清楚,所以我不能 100% 确定这完全符合您的要求,但这是我目前最好的猜测。

def get_right_number(numbers, i):
""" Recursive function to search for the first valid number to the right """

    if i >= len(numbers) - 1:
        right = -99
    else:
        right = numbers[i + 1]
        if right == -99:
            right = get_right_number(numbers, i+1)
    return right


def clean_missing_data(numbers):
    print(f'Input: {numbers}')

    if all(x == -99 for x in numbers):
        print('All values in list are invalid. Could not compute.')
        return

    clean_numbers = []

    for i in range(len(numbers)):
        if numbers[i] != -99:
            clean_numbers.append(numbers[i])
        else:
            valid_count = 0

            if i == 0:
                left = 0
            else:
                left = clean_numbers[i - 1]
                valid_count += 1

            right = get_right_number(numbers, i)
            if right == -99:
                right = 0
            else:
                valid_count += 1

            average = (left + right) / valid_count
            clean_numbers.append(average)

    print(f'Output: {clean_numbers}\n')
    return clean_numbers

这是我的测试用例(上面的 clean 方法中嵌入了 print):

clean_missing_data([1, 2, 3, 4, 5])
clean_missing_data([1, 2, 3, -99, 5])
clean_missing_data([-99, 2, 3, 4, 5])
clean_missing_data([-99, -99, 3, 4, 5])
clean_missing_data([1, 2, 3, 4, -99])
clean_missing_data([1, 2, 3, -99, -99])
clean_missing_data([1, -99, -99, -99, 5])
clean_missing_data([-99, -99, -99, -99, -99])

这里是输出:

Input: [1, 2, 3, 4, 5]
Output: [1, 2, 3, 4, 5]

Input: [1, 2, 3, -99, 5]
Output: [1, 2, 3, 4.0, 5]

Input: [-99, 2, 3, 4, 5]
Output: [2.0, 2, 3, 4, 5]

Input: [-99, -99, 3, 4, 5]
Output: [3.0, 3.0, 3, 4, 5]

Input: [1, 2, 3, 4, -99]
Output: [1, 2, 3, 4, 4.0]

Input: [1, 2, 3, -99, -99]
Output: [1, 2, 3, 3.0, 3.0]

Input: [1, -99, -99, -99, 5]
Output: [1, 3.0, 4.0, 4.5, 5]

Input: [-99, -99, -99, -99, -99]
All values in list are invalid.

请注意,当您有一串无效数字时,我们将获取最右边的有效数字并取其平均值。这个新的平均值将在计算下一个数字等时考虑。这执行了一种插值,但严格来说它不是线性插值。如果没有完整的要求,现在就必须这样做(按时且在预算内!)

如果您需要更改需求,您可以调整上面的代码,直到所有测试用例都满足您的需求。我也确信有一种更清洁的方法可以做到这一点,但我会把它留给你自己弄清楚。祝你好运!

【讨论】:

    【解决方案2】:

    您混淆了变量numberadjacent。惯例是讨论 enumerate(a) 返回一个 index 作为数组中的位置,并返回一个 element 作为元素本身。在这种情况下,您的代码变为

    def clean_missing_data():
        
        data_list = []
        
        for index, element in enumerate(a):
            
            if (element != -99):
    
                data_list.append(element)
                
            else:
                
                adjacent_left = a[index - 1]
                adjacent_right = a[index + 1]
                fill_in = (adjacent_left + adjacent_right) / 2    
                data_list.append(fill_in)
        
        return data_list
    
    a = [1,2,3,-99,5]
    
    check_data = clean_missing_data()
    
    print('original test case:', a)
    print('After clearing, the test case became:', check_data)
    

    给出[1, 2, 3, 4.0, 5],其中 4.0 当然等于 4

    您确实需要了解代码仍然存在一些问题。如果第一个或最后一个数字是 -99 怎么办?如果两个相邻的数字是-99怎么办?但这至少应该适用于您给出的示例!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-10
      • 2022-11-20
      • 2021-06-28
      • 2013-09-04
      • 2016-11-16
      • 2019-10-07
      • 1970-01-01
      相关资源
      最近更新 更多