这是here的延续。
我有一个B级,它包含一些数据(a和b字段)。
我正在将这些数据加载到Criteria类,以便通过标准并相应地更改调用函数avg
,func
,calcs
。
然后,我调用函数P
开始运行带有数据的程序。
代码:
import numpy as np
class B():
def __init__(self, a,b):
self.a = a
self.b = b
def __repr__(self):
return 'B(%s, %s)'%(self.a, self.b)
class Criteria():
def __init__(self, method, minimum, maximum, measures=None):
self.method = method
self.minimum = minimum
self.maximum = maximum
self.measures = measures
def __repr__(self):
if self.measures is None:
measures = 'measures: None'
else:
measures = [' measures:[']
for m in self.measures:
measures.append(' {}'.format(m))
measures.append(' ]')
measures = '\n'+ '\n'.join(measures)
return 'C({0.method},{0.minimum},{0.maximum}, {1})'.format(self, measures)
def calcs(self):
""" Update the `a` attribute from B class object according to
conditions
"""
if self.measures is not None:
for x in self.measures:
if (x.a > self.minimum and x.a < self.maximum):
x.a = 999
return self.measures
def avg(self, calcs=None):
"""Return the average of values"""
if calcs is None:
calcs = self.measures
if calcs is None:
return 'none'
elif len(calcs)==0:
return '[]'
else:
return np.average([x.a for x in calcs])
def func(self,calcs=None):
"""Return the minimum is input is array or multiple by 1000
if input is a number"""
if calcs is None:
calcs = self.measures
if calcs is None:
return 'none'
#elif len(calcs) == 0:
# return '[]'
else:
if isinstance(calcs, np.ndarray):
return np.amin([x.a for x in calcs])
else:
return calcs*1000
def P(alist):
# use these variables to hold the result of the corresponding execution
# use them in the list loop in order to be able to obtain a result from a `Criteria` evaluation
# and use it as input to the next
last_calcs_values = None
last_calcs_avg = None
last_calcs_m = None
for c in alist:
if c.method=='V':
last_calcs_values = c.calcs()
#print('calcs', last_calcs_values)
yield last_calcs_values
if c.method=='AVG':
if c.measures is None:
last_calcs_avg = c.avg(last_calcs_values)
else:
last_calcs_avg = c.avg()
#print('AVG', last_calcs_avg)
yield last_calcs_avg
if c.method == 'M':
if c.measures is None:
last_calcs_m = c.func(last_calcs_avg)
else:
last_calcs_m = c.func()
#print('M',last_calcs_m)
yield last_calcs_m
如果我使用数据:
b1 = np.array([B(10, 0.1), B(200,.5)])
c1 = Criteria('V', 1, 100, b1)
c2 = Criteria('AVG', 22, 220, None)
c3 = Criteria('M', 22, 220, None)
alist = [c1,c2,c3]
for i in P(alist):
print(i)
我收到:
[B(999, 0.1) B(200, 0.5)]
599.5
599500.0
这是正确的。但是它起作用是因为P
函数中的代码是硬编码的。
所以,
1)我的数据c1,c2,c3
按顺序使用方法V,AVG,M
。
所以,在P
函数中,我使用了:
yield last_calcs_values
last_calcs_avg = c.avg(last_calcs_values)
yield last_calcs_avg
last_calcs_m = c.func(last_calcs_avg)
yield last_calcs_m
相同的订单(硬编码)。
我的问题是如何将此代码用于任何订单。我必须以某种方式检查前一个方法值是什么并将其放入参数中(而不是放入c.func(last_calcs_avg)
2)在func
里面,我已经注释掉了这些行:
#elif len(calcs) == 0:
# return '[]'
因为如果我运行代码,它会给出:object of type 'numpy.float64' has no len()
。
我尝试检查类似于稍后在func
中的检查:
if isinstance(calcs, np.ndarray):
但没有成功。
3)有没有办法只获得最后的结果?
所以,而不是:
[B(999, 0.1) B(200, 0.5)]
599.5
599500.0
获得:
599500.0
答案 0 :(得分:1)
如果我正确阅读P
,则会保持3&#39;状态&#39;变量。 3个if子句可以按任何顺序调用(我认为可以使用if,ifthen,ifthen,else
语法编写,因为c.method
只匹配一个(c
。
但是列表中对象的顺序将决定值。 AVG
对象将使用最后一个V
对象设置的值。同样,M
将使用最后一个AVG
。如果首先传递AVG
,它将使用其计算中的初始None
值。
因此V1, AVG, M
的序列将使用由B
设置的V1
值。
在此序列V1, AVG, V2, M
中,M
使用上一个AVG
的值,该值取决于V1
;
avg
如果func
正在使用其值,或者至少测试必须匹配,则不应返回字符串。 []
是一个空列表,len()
为零,但'[]'
为2个字符的字符串,len
为2。
同样,None
是使用is None
测试的唯一值,而'none'
是4个字符的字符串。我在之前的问题中使用了类似的字符串,因为我们打印的是avg
的结果。当时我们还没有将它们用于进一步的计算。
如果您想确保AVG
和M
使用上一个V
中的值,则需要添加一些逻辑:
lastV, lastA, lastM = None,None,None
if c.method=='V':
lastV = <newV>
lastA, lastM = None,None
elif c.method=='A':
if lastV is None:
error
else:
lastA = <new A based on lastV>
elif c.method=='M':
if lastA is None:
error
<or update lastA>
else:
lastM = <new M based on lastA>
else:
error unknown c.method
所以我使用None
表示值无效。在这种情况下,它应该引发错误,或者应该计算新值。如果做得好,则应确保AVG
和M
都会根据最新的V
生成值。
从你的pastebin:
def avg(self, calcs=None):
"""Return the average of values"""
if calcs is None: # fun called without argument
calcs = self.measures # get value stored in self
if calcs is None: # in case that too was None
return '[]' # I would return None or []
# '[]' is a useless string
else:
if hasattr(calcs,'__len__'):
return np.average([x.a for x in calcs])
else:
return np.average(calcs)
np.average()
中哪些内容没有len
? len(np.arange(10))
运行,但没有a
属性
In [603]: avg(None,calcs=np.arange(10))
....
<ipython-input-602-48c9f6b255e1> in <listcomp>(.0)
8 else:
9 if hasattr(calcs,'__len__'):
---> 10 return np.average([x.a for x in calcs])
11 else:
12 return np.average(calcs)
AttributeError: 'numpy.int32' object has no attribute 'a'
具有__len__
个对象的数组或列表与其他列表或数组之间的B
。也许改进这个来测试dtype?或尝试/除外?
def avg(self,calcs = None): &#34;&#34;&#34;返回值的平均值&#34;&#34;&#34; .... 其他: 尝试: return np.average([x.a for x in calcs]) 除了AttributeError: return np.average(calcs)
In [606]: avg(None,calcs=np.arange(10))
Out[606]: 4.5
B
个对象的列表或数组有效:
In [609]: alist = [B(1,2),B(2,4),B(3,3)]
In [610]: avg(None, alist)
Out[610]: 2.0
In [611]: avg(None, np.array(alist))
Out[611]: 2.0