我需要 python 中 list_of_dicts_of_lists 的逐列中位数

I need column wise median of list_of_dicts_of_lists in python

我有这个数据:

list_of_dicts_of_lists = [
    {'a': [1,2], 'b': [3,4], 'c': [3,2], 'd': [2,5]}
    {'a': [2,2], 'b': [2,2], 'c': [1,6], 'd': [4,7]}
    {'a': [2,2], 'b': [5,2], 'c': [3,2], 'd': [2,2]}
    {'a': [1,2], 'b': [3,4], 'c': [1,6], 'd': [5,5]} 
    ]

我需要这个结果:

median_dict_of_lists = (
    {'a': [1.5,2], 'b': [3,3], 'c': [2,4], 'd': [3,5]}
    )

...其中每个值都是上面相应列的中位数。

我需要可用的模式字典和不存在模式时的中值字典。我能够通过将每个字典串起来,获取字符串列表的模式,然后 ast.literal_eval(most_common_string) 返回一个字典来快速而肮脏地 statistics.mode(),但是在没有模式的情况下我需要一个按列的中位数.

我知道怎么用statistics.median();然而,将它应用于这种情况的嵌套符号,按列排列,让我感到困惑。

数据都是浮点数;我把它写成 int 只是为了更容易阅读。

您可以将 statistics.medianitertools.groupby 一起使用:

import statistics
import itertools
list_of_dicts_of_lists = [
  {'a': [1,2], 'b': [3,4], 'c': [3,2], 'd': [2,5]},
  {'a': [2,2], 'b': [2,2], 'c': [1,6], 'd': [4,7]},
  {'a': [2,2], 'b': [5,2], 'c': [3,2], 'd': [2,2]},
  {'a': [1,2], 'b': [3,4], 'c': [1,6], 'd': [5,5]} 
]
new_listing = [(a, list(b)) for a, b in itertools.groupby(sorted(itertools.chain(*map(lambda x:x.items(), list_of_dicts_of_lists)), key=lambda x:x[0]), key=lambda x:x[0])]
d = {a:zip(*map(lambda x:x[-1], b)) for a, b in new_listing}
last_data = ({a:[statistics.median(b), statistics.median(c)] for a, [b, c] in d.items()},)

输出:

({'a': [1.5, 2.0], 'b': [3.0, 3.0], 'c': [2.0, 4.0], 'd': [3.0, 5.0]},)

您可以对 numpy 使用以下字典理解:

import numpy as np
median_dict_of_lists = {i : list(np.median([x[i] for x in list_of_dicts_of_lists], axis=0)) 
                    for i in 'abcd'}

哪个returns相同:

{'a': [1.5, 2.0], 'c': [2.0, 4.0], 'b': [3.0, 3.0], 'd': [3.0, 5.0]}

解释一下,np.median([x[i] for x in list_of_dicts_of_lists], axis=0),嵌入在字典理解中,正在遍历 ['a', 'b', 'c', 'd'] 中的每个键 i,并为你的所有字典获取每个键的中值你的原始列表。这个中位数通过字典理解语法被分配给一个具有适当键的新字典。

字典理解语法有很好的解释, and the documentation for np.median很好地解释了函数本身

您还可以使用有意义的名称将其分解成小步骤,使解决方案更易于维护。例如:

# combine dictionary arrays into a 3d matrix, removing dictionary keys
valueMatrix3D = [ list(row.values()) for row in list_of_dicts_of_lists ]

# compute the median for each row's array (axis 1)
medianArrays  = np.median(valueMatrix3D,axis=1)

# reassemble into a dictionary with original keys
medianDict = { key:list(array) for key,array in zip(list_of_dicts_of_lists[0] ,medianArrays) }