2017-02-21 16 views
1

Я работаю над проектом кодирования, чтобы определить, загрязнены ли воды или нет. Для одного типа загрязнения вода считается загрязненной, если более 10% образцов в 5-летнем окне находятся за пределами заданных критериев. Для решения этой проблемы, я сделал следующий кодВложенные итерации с помощью счетчиков

def testLocationForConv(overDict): 
    impairedList=[] 
    for pollutant in overDict: 
      for date in dateList: 
      total=0 
      over=0 
      for compDate in dateList: 
       if int(date[0])+1825>int(compDate[0]) and int(date[0])-1825<int(compDate[0]): 
        total=total+1 
        if date[1]: 
         over=over+1 

      if total!=0: 
       if over/total>=.1: 
        if pollutant not in impairedList: 
         impairedList.append(pollutant) 
    return impairedList 

код принимает словарь, и будет производить список загрязняющих веществ для организма воды. Ключами словаря являются строки с именами загрязнителей, а значение - датаList, список кортежей, с датой теста в качестве первого элемента, а второй - логическое значение, указывающее, является ли значение, измеренное в этот день, над или под приемлемым значением

Ниже приведен пример "overDict", что код будет принимать в качестве входного сигнала:

{ 'кишечной палочки': [('40283', False), ('40317 ', False), (' 40350 ', False), (' 40374 ', False), (' 40408 ', True), (' 40437 ', True), (' 40465 ', False), (' 40505 ',' False), ('40619', False), ('40647', False), ('40681', False), ('40519', False) , ('40710', False), ('40738', False), ('40772', False), ('40801', True), ('40822', False) ('40980', False), ('41011', False), ('41045', False), ('41067', False), ('41228', False), ('41388', False) 41409 ', False), (' 41438 ', False), (' 41597 ', False), (' 41710 ', False), (' , False), ('41773', False), ('41802', False), ('41834', False)]}

в этом примере, код говорит, что это excedance, но оно не должно так как менее 10% тестов были «истинными», и все тесты проводились в течение 5-летнего периода. Что здесь неправильно?

Update: Когда я использую этот словарь в качестве overDict, код считает эти данные не превышение, даже если в окне, которое начинается 40745 2 из 11 значений находятся за пределом

{'copper': [('38834', False), ('38867', False), ('38897', False), 
('40745', False), ('40764', False), ('40799', False), ('41024', True), 
('41047', False), ('41072', True), ('41200', False), ('41411', False), 
('41442', False), ('41477', False), ('41502', False)]} 

Чтобы устранить неполадки, я напечатал slide_windows в строках кода «для кортежей» и «для окна», и я получил это вместо списка, где каждая другая дата начала используется один раз.

[[38834, 0, 1]] 
[[38834, 0, 1]] 
[[38834, 0, 1]] 
[[38834, 0, 1]] 
[[38834, 0, 1]] 
[[38834, 0, 1]] 
[[38834, 0, 1]] 
+0

Ваш отступ отключен, вы можете исправить его? – TemporalWolf

+1

у нас нет 'dateList', и вы должны исправить свой отступ. –

+0

Хорошая возможность немного очистить свой код и сделать его более читаемым. Например, у вас длинная строка с сложным условным и повторяющимся магическим числом. Поверните это в простое условие, которое вызывает логическую функцию. –

ответ

0
results = {} 
range = 1825 
for name, value in overDict.items(): 
    sliding_windows = [] 
    good = True 
    for tuple in value: 
     # Add this take information to any windows it falls into 
     for window in sliding_windows: 
      if window[0] > int(tuple[0]) - range: 
       window[1] += tuple[1] 
       window[2] += 1 
     # start a new window with this date 
     sliding_windows.append([int(tuple[0]), tuple[1], 1]) 
    for window in sliding_windows: 
     if window[1]/float(window[2]) > .1: 
      good = False 
    results[name] = good 

Это создает список даты начала sliding_windows:

[[40283, 3, 35], [40317, 3, 34], [40350, 3, 33], [40374, 3, 32], 
[40408, 3, 31], [40437, 2, 30], [40465, 1, 29], [40505, 1, 28], 
[40521, 1, 27], [40569, 1, 26], [40597, 1, 25], [40619, 1, 24], 
[40647, 1, 23], [40681, 1, 22], [40710, 1, 21], [40738, 1, 20], 
[40772, 1, 19], [40801, 1, 18], [40822, 0, 17], [40980, 0, 16], 
[41011, 0, 15], [41045, 0, 14], [41067, 0, 13], [41228, 0, 12], 
[41388, 0, 11], [41409, 0, 10], [41438, 0, 9], [41466, 0, 8], 
[41557, 0, 7], [41592, 0, 6], [41710, 0, 5], [41743, 0, 4], 
[41773, 0, 3], [41802, 0, 2], [41834, False, 1]] 

и вычисляет каждую скорость окна, возвращая True/False в словаре, если это находится над/под. Возможно, стоит не включать окна, которые не занимают достаточно времени, так как в этом случае любые удары в последних 10 измерениях будут считаться сбоем.Я бы, вероятно, сделал это, взяв последнее измерение и выбросив все окна, которые короче 5 лет (за исключением, может быть, первого, так что вы можете получить частичный результат, если доступно менее 5 лет):

cutoff = int(value[-1][0]) - range 
for tuple in value: 
    ... 
    if int(tuple[0]) < cutoff or len(sliding_windows) == 0: 
     sliding_windows.append([int(tuple[0]), tuple[1], 1]) 

Затем генерирует:

sliding_windows:

[[40283, 3, 35]]

Заметим, что это возвращает True если хорошо, False если плохо:

{'Escherichia coli': True}

Примечание: Это неявно преобразовать логический True/False в 1/0, добавив их вместе window[1] += tuple[1]. Вот почему последняя запись [41834, False, 1], что эквивалентно [41834, 0, 1] для наших целей.

+0

большое вам спасибо! Итак, в этом коде индект такой же, как overDict в исходном коде? –

+0

также, ваш код оставляет общее количество и больше, но никогда не использует их. есть ли причина для этого? –

+0

@AmeliaMcClure Нет, это остатки моей первоначальной попытки. Я удалил их :) – TemporalWolf

0

Эта логика делает то, что вы хотите?

def give5yrSlice(your_list, your_date): 
    return [(dat, val) for dat, val in your_list if your_date - 1825 < int(dat) < your_date + 1825] 


def testAllSingle5yrFrame(your_list): 
    five_years = [year1, year2, year3, year4, year5] 

    return all(testSingleSampleSet(give5yrSlice(your_list, d)) for d in five_years) 


def testSingleSampleSet(your_list): 
    all_passed_values = [passed for date, passed in your_list if passed] 

    return len(all_passed_values)/float(len(your_list)) > 0.1 


def testLocationForConv(overDict): 
    return all(testAllSingle5yrFrame(your_list) for your_list in overDict.values()) 

Вы звоните testLocationForConv(your_dict_with_data).

+0

, так что эта часть того, что я пытаюсь сделать, но также я пытаюсь сделать это для всех 5-летних подмножеств данных, в то время как это будет смотреть на все это сразу. Но, спасибо, это полезно начать! –

+0

Я обновил решение. Вам нужно немного настроить его, я думаю, – Elmex80s