【问题标题】:Normalising an array of dicts which contain both values directly and other dicts, across whole array在整个数组中规范化包含直接值和其他字典的字典数组
【发布时间】:2016-12-28 05:28:20
【问题描述】:

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

[
        {
            '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 中的每个键值对相同​​。

我该怎么做?

我想找到一种比创建额外的最大/最小/范围值和字典更快的方法,因为这是我现有的方法(这是计算 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()}

有没有一种以这种方式标准化所有内容的单线解决方案?

【问题讨论】:

  • 我试图让你的 dict 可读。那没有用。您的 python 代码在某处缺少,;无效。
  • 还有:你的方法是什么?你试过什么?你在哪里遇到问题? 您的确切问题是什么?
  • } 之后的第 16 行缺少逗号
  • 注意,感谢您更改格式@MarcusMüller
  • 嗨@MarcusMüller 我现在已经把问题说得更清楚了,如果您需要更多说明,请告诉我。

标签: python arrays dictionary normalization


【解决方案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

编辑:

如果你想分别考虑 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

【讨论】:

  • 嗨@BPL,这对数组中的所有值进行了规范化。我只是想分别规范化每个键,例如对于value 中的值,在其范围内(21-900)进行归一化,对于openValues: {'a' 中的值,仅在其范围内进行归一化,例如24-7811)。
  • @DhruvGhulati 啊,好的,我现在明白了,让我回顾一下我的问题,然后添加一个新的解决方案 :)
  • @DhruvGhulati 好的,我已经为你的函数扩展了代码,希望对你有帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-30
  • 1970-01-01
  • 1970-01-01
  • 2011-02-10
相关资源
最近更新 更多