我有一个包含元组列表的字典的字典:
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.diff
和numpy.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.]]])
一旦你得到结果,你可以重建字典或任何你需要的。