我有这些数据:
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]}
)
...其中每个值是上面各列的中位数。
当没有模式存在时,我需要可用的模式字典和中值字典。通过对每个字典进行字符串处理,获得字符串列表模式,然后statistics.mode()
返回到字典,我能够快速而肮脏ast.literal_eval(most_common_string)
,但是在没有模式的情况下我需要列明中值
我知道如何使用statistics.median()
;然而,列式显示将嵌套符号应用于此案例,令我眼花缭乱。
数据全部是浮点数;我把它写成int只是为了更容易阅读。
答案 0 :(得分:4)
您可以将statistics.median
与itertools.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]},)
答案 1 :(得分:3)
您可以对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'}
使用以下词典理解:
{'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)
要解释一下,嵌入在词典理解中的i
会遍历['a', 'b', 'c', 'd']
中的每个键location
,并获取原始中所有词组的每个键的中位数dicts列表。通过字典理解语法将该中值分配给具有适当密钥的新字典。
字典理解语法here有一个很好的解释,documentation for np.median很好地解释了函数本身
答案 2 :(得分:2)
您还可以使用有意义的名称将其分解为小步骤,以使解决方案更易于维护。例如:
# 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) }