我正在进行一个编码项目,以确定水是否受到污染。对于一种类型的污染,如果超过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该代码需要一本字典,并将生成一份水体污染物清单。字典的键是带有污染物名称的字符串,值是dateList (元组列表),测试日期为第一项,第二项为布尔值,指示当天测量的值是否超过或低于可接受的值。
下面是代码将作为输入的"overDict“示例:
{“大肠杆菌”:('40283',假),('40317',假),('40350',假),('40374',假),('40408',真),('40437',真),('40465',假),('40505',假),('40521',假),('40569',假),('40597',假),('40619',假),('40647',假),('40681',假),('40710',假),('40738',假),('40772',假),('40801',真),('40822',假),('40980',假),('41011',假),('41045',假),('41067',假),('41228',假),('41388',假),('41409',假),('41438',假),('41466',假),('41557',('41592',假),('41710',假),('41743',假),('41773',假),('41802',假),('41834',假)}
在这个例子中,代码说这是多余的,但不应该是这样,因为不到10%的测试是“真”的,所有的测试都是在5年的时间内完成的。这里有什么不对的?
更新:当我使用此字典作为overDict时,代码认为这些数据不是多余的,即使在启动40745的窗口中,11个值中有2个超出了限制。
{'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)]}为了排除故障,我在"for tuple“和"for window”代码行下打印了sliding_windows,我得到的是这个列表,而不是使用每个不同开始日期一次的列表。
[[38834, 0, 1]]
[[38834, 0, 1]]
[[38834, 0, 1]]
[[38834, 0, 1]]
[[38834, 0, 1]]
[[38834, 0, 1]]
[[38834, 0, 1]]发布于 2017-02-21 21:15:43
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添加到window[1] += tuple[1],从而隐式地将它们转换为1/0。这就是为什么最后一个条目是[41834, False, 1],对于我们的目的来说,它等同于[41834, 0, 1]。
发布于 2017-02-21 20:48:31
这个逻辑能做你想做的事吗?
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)打电话。
https://stackoverflow.com/questions/42377343
复制相似问题