在整个数组中规范化一个包含直接值和其他字典的字典数组
Normalising an array of dicts which contain both values directly and other dicts, across whole 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
}
}
]
我想将每个键中的所有值以及键中每个字典中的值标准化为 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
中的每个键值对一样。
我该怎么做?
我想找到一种比必须创建额外的 max/min/range 值和指令更快的方法,因为这是我现有的方法(这是计算 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] 之间归一化,考虑到数组中所有可能项的最小值和最大值,这里有一个可能的解决方案:
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
编辑:
如果你想分别考虑 values 和 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
我有一个巨大的数组,看起来像(示例行):
[
{
'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
}
}
]
我想将每个键中的所有值以及键中每个字典中的值标准化为 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
中的每个键值对一样。
我该怎么做?
我想找到一种比必须创建额外的 max/min/range 值和指令更快的方法,因为这是我现有的方法(这是计算 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] 之间归一化,考虑到数组中所有可能项的最小值和最大值,这里有一个可能的解决方案:
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
编辑:
如果你想分别考虑 values 和 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