我试图找到一种更加pythonic的方式来做这个条件总和:
...
for i in xrange(len(eventVqts)-2, 0, -1):
events[eventVqts[i].TimeStamp] = total(eventVqts, sourceVqts, i)
mins[eventVqts[i].TimeStamp] = minx(eventVqts, sourceVqts, i)
maxs[eventVqts[i].TimeStamp] = maxx(eventVqts, sourceVqts, i)
avgs[eventVqts[i].TimeStamp] = avgx(eventVqts, sourceVqts, i)
sums[eventVqts[i].TimeStamp] = sumx(eventVqts, sourceVqts, i)
times[eventVqts[i].TimeStamp] = eventVqts[i + 1].TimeStamp
durations[eventVqts[i].TimeStamp] = (eventVqts[i+1].TimeStamp - eventVqts[i].TimeStamp).TotalMilliseconds
...
def total(events, source, index):
start = events[index].TimeStamp
end = events[index+1].TimeStamp
filtered = [s.Variant.Double for s in source if s.TimeStamp >= start and s.TimeStamp < end]
if len(filtered) > 0:
return filtered[-1] - filtered[0]
else:
Log.Error('No filtered records found')
return 0
def minx(events, source, index):
start = events[index].TimeStamp
end = events[index+1].TimeStamp
filtered = [s.Variant.Double for s in source if s.TimeStamp >= start and s.TimeStamp < end]
if len(filtered) > 0:
return min(filtered)
else:
return 0
def maxx(events, source, index):
start = events[index].TimeStamp
end = events[index+1].TimeStamp
filtered = [s.Variant.Double for s in source if s.TimeStamp >= start and s.TimeStamp < end]
if len(filtered) > 0:
return max(filtered)
else:
return 0
def avgx(events, source, index):
start = events[index].TimeStamp
end = events[index+1].TimeStamp
filtered = [s.Variant.Double for s in source if s.TimeStamp >= start and s.TimeStamp < end]
if len(filtered) > 0:
return sum(filtered) / float(len(filtered))
else:
return 0
def sumx(events, source, index):
start = events[index].TimeStamp
end = events[index+1].TimeStamp
filtered = [s.Variant.Double for s in source if s.TimeStamp >= start and s.TimeStamp < end]
if len(filtered) > 0:
return sum(filtered)
else:
return 0
因此,反向迭代,从第2个到最后一个,并获取相对于事件数据的源数据的聚合。不要获得第一个值的聚合。
events {}和source {}都是.NET类型的字典,如下所示:
.Variant
.TimeStamp
.Variant结构几乎是旧的VB Variant类型。
对于事件中的每个事件,我想要查找源中的所有值&gt; =事件的时间戳,并且&lt;下一个事件的时间戳。
我上面的详细代码有效,但它似乎缺乏与python关联的某种优雅,就像我正在努力做到这一点。
注意:这是嵌入式IronPython环境,因此我无法导入numpy或任何其他模块。我只能使用IP2.6运行时。此外,我无法弹出.NET程序集,因此我的代码必须作为脚本工作。我在这里发布了这个,因为我没有看到除了环境之外它是特定的IronPython。我可以部署脚本(作为模型中对象的字符串属性),但不能部署程序集。我所拥有的只是直接的文本代码。
我打破了开始和结束变量,因为似乎理解语法并不理解嵌入的方括号。
有多糟糕?有没有办法用发电机做到这一点?他们都会过滤相同的,所以如果我可以用
返回一个对象.min
.max
.sum
.total
.avg
那会让我很开心。特别是如果它摆脱了冗余代码。
答案 0 :(得分:0)
for i in xrange(len(event_vqts)-2, 0, -1):
start = event_vqts[i].TimeStamp
end = event_vqts[i + 1].TimeStamp
times[start] = end
durations[start] = (end - start).TotalMilliseconds / float(1000)
filtered = [s.Variant.Double for s in source_vqts if s.TimeStamp >= start and s.TimeStamp < end]
count = len(filtered)
if count > 0:
total = float(filtered[-1] - filtered[0])
if total < 0:
total = float((filtered[-1] + rollover) - filtered[0])
totals[start] = total
counts[start] = count
mins[start] = min(filtered)
maxs[start] = max(filtered)
avgs[start] = sum(filtered) / float(count)
sums[start] = sum(filtered)
stds[start] = std(filtered)
starting_values[start] = filtered[0]
ending_values[start] = filtered[-1]
else:
totals[start] = 0
counts[start] = 0
mins[start] = 0
maxs[start] = 0
avgs[start] = 0
sums[start] = 0
stds[start] = 0
starting_values[start] = 0
ending_values[start] = 0
它似乎满足了我的需求。
虽然现在我想知道发电机对于更大的设备是否更具性能?我将研究@adam-smith的解决方案,因为它看起来很干净。
答案 1 :(得分:0)
考虑将整个事物包装在一个知道如何过滤自身的对象中。
class EventInterface(list):
# pass in the `source` list
def filter(event, index): # returns a generator
start = event[index].TimeStamp
end = event[index+1].TimeStamp
return (s for s in self if start <= s.TimeStamp < end)
sources = EventInterface(sourceVqts)
for i in range(len(eventVqts)-2, 0, -1):
filtered = map(attrgetter('Variant.Double'), sources.filter(eventVqts, i))
然后你可以用结果做你喜欢的事。
def avg(sources):
return float(sum(sources)) / len(sources)
def total(sources):
return sources[-1] - sources[0]
for i in range(len(eventVqts)-2, 0, -1):
filtered = map(attrgetter('Variant.Double'), sources.filter(eventQvts, i))
the_sum = sum(filtered)
the_avg = avg(filtered)
the_total = total(filtered)
# etc....