规范化整个数组中直接包含值和其他dicts的dicts数组

时间:2016-08-21 16:25:35

标签: python arrays dictionary normalization

我有一个巨大的数组,看起来像(示例行):

[
        {
            '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()}

是否有以这种方式规范化所有内容的单行解决方案?

1 个答案:

答案 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