我有一个巨大的数组,看起来像(示例行):
[
{
'value':21,
'openValues':{
'a':24,
'b':56,
'c':78
}
},
{
'value':12,
'openValues':{
'a':98,
'b':3
}
},
{
'value':900,
'openValues':{
'a':7811,
'b':171,
'c':11211,
'd':4231
}
}
]
我希望将每个键中的所有值和一个键中每个dict中的值标准化为0到1.例如:
以下是要执行的计算:
[{
'value':(21-12)/(900-12),
'openValues':{'a':(24-24)/(7811-24),'b':(56-3)/(171-3),'c':(78-78)/(11211-78)}
},
{
'value':(12-12)/(900-12),
'openValues':{'a':(98-24)/(7811-24),'b':(3-3)/(171-3)}
},
{
'value':(900-12)/(900-12),
'openValues':{'a':(7811-24)/(7811-24),'b':(171-3)/(171-3),'c':(11211-78)/(11211-78),'d':(4231-4231)/(4231-4231)}
}]
如您所见,每个value
已经标准化(减去最小值,然后除以值范围),并且与openValues
中的每个键值对相同。
我该怎么做?
我想找到一个更快的方法,而不是创建额外的最大/最小/范围值和dicts,因为这是我现有的方法(这是计算openValues
字典的最大值和最小值的示例:
openValuesMin = {}
openValuesMax = {}
for i, dict in enumerate(array):
for property,value in dict['openValues'].items():
if property not in openValuesMax:
openValuesMax[property] = 0
if openValuesMax[property]<value:
openValuesMax[property]=value
if property not in openValuesMin:
openValuesMin[property] = 0
if openValuesMin[property]>value:
openValuesMin[property] = value
openValuesRange = {key: openValuesMax[key] - openValuesMin.get(key, 0) for key in openValuesMax.keys()}
是否有以这种方式规范化所有内容的单行解决方案?
答案 0 :(得分:1)
我不确定我是否已经很好地理解了你的问题,但假设你想在[0-1]之间进行归一化,考虑到最小值和最小值。来自阵列中所有可能项目的最大值,这是一个可能的解决方案:
array = [
{
'value': 21,
'openValues': {
'a': 24,
'b': 56,
'c': 78
}
},
{
'value': 12,
'openValues': {
'a': 98,
'b': 3
}
},
{
'value': 900,
'openValues': {
'a': 7811,
'b': 171,
'c': 11211,
'd': 4231
}
}
]
def normalize(v0, v1, t):
return float(t - v0) / float(v1 - v0)
def f(v0, v1, item):
return {
"value": normalize(v0, v1, item["value"]),
"openValues": {
k: normalize(v0, v1, v) for k, v in item["openValues"].iteritems()
}
}
values = sum([[item["value"]] + item["openValues"].values()
for item in array], [])
v_min, v_max = min(values), max(values)
output = [f(v_min, v_max, item) for item in array]
print output
编辑:
如果要分别考虑值和openValues进行规范化,可以像这样扩展上面的代码
array = [
{
'value': 21,
'openValues': {
'a': 24,
'b': 56,
'c': 78
}
},
{
'value': 12,
'openValues': {
'a': 98,
'b': 3
}
},
{
'value': 900,
'openValues': {
'a': 7811,
'b': 171,
'c': 11211,
'd': 4231
}
}
]
def normalize(v0, v1, t):
return float(t - v0) / float(v1 - v0)
def f(vmin0, vmax0, vmin1, vmax1, item):
return {
"value": normalize(vmin0, vmax0, item["value"]),
"openValues": {
k: normalize(vmin1, vmax1, v) for k, v in item["openValues"].iteritems()
}
}
values = [item["value"] for item in array]
v_min0, v_max0 = min(values), max(values)
values = sum([item["openValues"].values() for item in array], [])
v_min1, v_max1 = min(values), max(values)
output = [f(v_min0, v_max0, v_min1, v_max1, item) for item in array]
print output