计算字典的字典中的delta



我有一个包含元组列表的字典的字典:

mydict:{'A1':{'week1': [(1,1,34),(1,2,3),(1,3,10),(2,1,3),(2,2,9)...()],
'week2': [(1,1,4),(1,2,11),(1,3,8),(2,1,5),(2,2,7)...()],
...
'week19': [(1,1,12),(1,2,13),(1,3,32),(2,1,45),(2,2,15)...()],
'week20': [(1,1,43),(1,2,30),(1,3,6),(2,1,7),(2,2,4)...()]}
'A2':{'week1': [(1,1,6),(1,2,4),(1,3,2),(2,1,87),(2,2,32)...()],
'week2': [(1,1,32),(1,2,15),(1,3,43),(2,1,2),(2,2,12)...()],
...
'week20': [(1,1,3),(1,2,3),(1,3,16),(2,1,17),(2,2,11)...()]}
...
} 

我想计算字典中每个元组中第三个元素(它们的前两个元素是相同的)的增量,每周之间(例如,week1和week2,…)第19周和第20周),并把它们作为新字典放在主字典中。所以我想要的结果可能是这样的:

out_dict:{'A1':{'week1': [(1,1,34),(1,2,3),(1,3,10),(2,1,3),(2,2,9)...()],
'week2': [(1,1,4),(1,2,11),(1,3,8),(2,1,5),(2,2,7)...()],
...
'week19': [(1,1,12),(1,2,13),(1,3,32),(2,1,45),(2,2,15)...()],
'week20': [(1,1,43),(1,2,30),(1,3,6),(2,1,7),(2,2,4)...()],
'delta_wk1_wk2':[(1,1,30),(1,2, 8),(1,3,2),(2,1,2),(2,2,2)...()],
'delta_wk20_wk19':[(1,1,31),(1,2, 23),(1,3,26),(2,1,38),(2,2,11)...()]
...
}
'A2':{'week1': [(1,1,6),(1,2,4),(1,3,2),(2,1,87),(2,2,32)...()],
'week2': [(1,1,32),(1,2,15),(1,3,43),(2,1,2),(2,2,12)...()],
...
'week19': [(1,1,7),(1,2,0),(1,3,2),(2,1,33),(2,2,10)...()],
'week20': [(1,1,3),(1,2,3),(1,3,16),(2,1,17),(2,2,11)...()]}
...
'delta_wk1_wk2':[(1,1,26),(1,2, 11),(1,3,41),(2,1,85),(2,2,20)...()],
'delta_wk20_wk19':[(1,1,4),(1,2, 3),(1,3,14),(2,1,14),(2,2,1)...()]
} 

要获得每对周,您可以使用成对迭代器,您可以查看itertools菜谱以查看实现;它看起来像这样:

from itertools import tee
def pairwise(iterable):
x, y = tee(iterable)
next(y, None)
return zip(x, y)

然后你可以在你的字典条目上使用它:

def add_deltas(data):
for first, second in pairwise(data.keys()):
deltas = []
for a, b in zip(data[first], data[second]):
if b:
deltas.append((a[0], a[1], abs(a[2] - b[2])))
data[f'delta_{first}_{second}'] = deltas

使用这个循环遍历你的字典:

for v in mydict.values():
add_deltas(v)

据我所知,这是一个使用Numpy的解决方案,因为它被标记。

我只使用A1组的周,有一点变化来显示排序问题:

data = {
'week8': [(1,1,34),(1,2,3),(1,3,10),(2,1,3),(2,2,9)],
'week9': [(1,1,4),(1,2,11),(1,3,8),(2,1,5),(2,2,7)],
'week10': [(1,1,12),(1,2,13),(1,3,32),(2,1,45),(2,2,15)],
'week11': [(1,1,43),(1,2,30),(1,3,6),(2,1,7),(2,2,4)]
}

首先要确保键是排序的,但是给定键

format there is an issue:
data_tmp = sorted(zip(data.keys(), data.values()))
list(data_tmp)

结果是:

# [('week10', [(1, 1, 12), (1, 2, 13), (1, 3, 32), (2, 1, 45), (2, 2, 15)]),
#  ('week11', [(1, 1, 43), (1, 2, 30), (1, 3, 6), (2, 1, 7), (2, 2, 4)]),
#  ('week8', [(1, 1, 34), (1, 2, 3), (1, 3, 10), (2, 1, 3), (2, 2, 9)]),
#  ('week9', [(1, 1, 4), (1, 2, 11), (1, 3, 8), (2, 1, 5), (2, 2, 7)])]

首先,让我们定义一个方法,将周数提取为整数:

import re
def week_number(wk_string):
tmp = [ch for ch in wk_string if ch.isdigit()]
return int(('').join(tmp))

例如week_number('week43') #=> 43


让我们排序数据

data_sorted = sorted(zip([week_number(wk_string) for wk_string in data.keys()], data.values()))
list(data_sorted)
# [(8, [(1, 1, 34), (1, 2, 3), (1, 3, 10), (2, 1, 3), (2, 2, 9)]),
#  (9, [(1, 1, 4), (1, 2, 11), (1, 3, 8), (2, 1, 5), (2, 2, 7)]),
#  (10, [(1, 1, 12), (1, 2, 13), (1, 3, 32), (2, 1, 45), (2, 2, 15)]),
#  (11, [(1, 1, 43), (1, 2, 30), (1, 3, 6), (2, 1, 7), (2, 2, 4)])]

方法就绪后,让我们将数据转换为维度为(week_number, i, j)的Numpy数组。

考虑索引从0开始,因此将其考虑在内。

dim_w = 52
dim_i = max([e[0] for _, value in data_sorted for e in value ])
dim_i #=> 2
dim_j = max([e[1] for _, value in data_sorted for e in value ])
dim_j #=> 3

将数组初始化为0,然后循环填充值:

import numpy as np
ary = np.zeros((52, dim_i, dim_j))
for num_week, week_data in data_sorted:
for i, j, val in week_data:
ary[num_week-1, i-1, j-1] = val

在这里您可以看到所考虑的周(8至12周)的值:

ary[7:11,:,:] # indexes starts from zero
# array([[[34.,  3., 10.],
#         [ 3.,  9.,  0.]],
# 
#        [[ 4., 11.,  8.],
#         [ 5.,  7.,  0.]],
# 
#        [[12., 13., 32.],
#         [45., 15.,  0.]],
# 
#        [[43., 30.,  6.],
#         [ 7.,  4.,  0.]]])

要获得相邻行之间的差值,只需使用numpy.diffnumpy.abs来获得绝对值:

diff = np.abs(np.diff(ary, axis=0))
# just to see a slice of the result:
diff[5:12,:,:]
# array([[[ 0.,  0.,  0.],
#         [ 0.,  0.,  0.]],
# 
#        [[34.,  3., 10.],
#         [ 3.,  9.,  0.]],
# 
#        [[30.,  8.,  2.],
#         [ 2.,  2.,  0.]],
# 
#        [[ 8.,  2., 24.],
#         [40.,  8.,  0.]],
# 
#        [[31., 17., 26.],
#         [38., 11.,  0.]],
# 
#        [[43., 30.,  6.],
#         [ 7.,  4.,  0.]],
# 
#        [[ 0.,  0.,  0.],
#         [ 0.,  0.,  0.]]])

一旦你得到结果,你可以重建字典或任何你需要的。

相关内容

  • 没有找到相关文章