I got a defaultdict with lists as values and tuples as keys (ddict in the code below). I want to find the min and max of values for a given set of keys. The keys are given as a numpy array. The numpy array is a 3D array containing the keys. Each row of the 3D array is the block of keys for which we need to find the min and max i.e. for each row we take the corresponding 2D array entries, and get the values corresponding to those entries and find the min and max over those values. I need to do it for all the rows of the 3D array.

from operator import itemgetter
import numpy as np

ddict =  {(1.0, 1.0): [1,2,3,4], (1.0, 2.5): [2,3,4,5], (1.0, 3.75): [], (1.5, 1.0): [8,9,10], (1.5, 2.5): [2,6,8,19,1,31], (1.5,3.75): [4]}
indA = np.array([ [ [( 1.0, 1.0), ( 1.0, 3.75)], [(1.5,1.0), (1.5,3.75)] ], [ [(1.0, 2.5), (1.5,1.0)], [(1.5, 2.5), (1.5,3.75)] ] ])

mins = min(ddict, key=itemgetter(*[tuple(i) for b in indA for i in b.flatten()]))
maxs = max(ddict, key=itemgetter(*[tuple(i) for b in indA for i in b.flatten()]))

I tried the above code to get the output of

min1 = min([1,2,3,4,8,9,10,4]) & min2 = min([2,3,4,5,8,9,10,2,6,8,19,1,31,4]) and max1= max([1,2,3,4,8,9,10,4]) & max2 = max([2,3,4,5,8,9,10,2,6,8,19,1,31,4])

I want to calculate the min and max for every 2D array in the numpy array. Any workaround ? Why my code is not working ? It gives me error TypeError: tuple indices must be integers or slices, not tuple

推荐答案

Here is what I think you're after:

import numpy as np

# I've reformatted your example data, to make it a bit clearer
# no change in content though, just different whitespace
# whether d is a dict or defaultdict doesn't matter
d = {
    (1.0, 1.0): [1, 2, 3, 4],
    (1.0, 2.5): [2, 3, 4, 5],
    (1.0, 3.75): [],
    (1.5, 1.0): [8, 9, 10],
    (1.5, 2.5): [2, 6, 8, 19, 1, 31],
    (1.5, 3.75): [4]
}

# indA is just an array of indices, avoid capitals in variable names
indices = np.array(
    [
        [[(1.0, 1.0), (1.0, 3.75)], [(1.5, 1.0), (1.5, 3.75)]],
        [[(1.0, 2.5), (1.5, 1.0)], [(1.5, 2.5), (1.5, 3.75)]]
    ])

for group in indices:
    # you flattened each grouping of indices, but that flattens
    # the tuples you need intact as well:
    print('not: ', group.flatten())
    # Instead, you just want all the tuples:
    print('but: ', group.reshape(-1, group.shape[-1]))

# with that knowledge, this is how you can get the lists you want
# the min and max for
for group in indices:
    group = group.reshape(-1, group.shape[-1])
    values = list(x for key in group for x in d[tuple(key)])
    print(values)

# So, the solution:
result = [
    (min(vals), max(vals)) for vals in (
        list(x for key in grp.reshape(-1, grp.shape[-1]) for x in d[tuple(key)])
        for grp in indices
    )
]
print(result)

Output:

not:  [1.   1.   1.   3.75 1.5  1.   1.5  3.75]
but:  [[1.   1.  ]
 [1.   3.75]
 [1.5  1.  ]
 [1.5  3.75]]
not:  [1.   2.5  1.5  1.   1.5  2.5  1.5  3.75]
but:  [[1.   2.5 ]
 [1.5  1.  ]
 [1.5  2.5 ]
 [1.5  3.75]]
[1, 2, 3, 4, 8, 9, 10, 4]
[2, 3, 4, 5, 8, 9, 10, 2, 6, 8, 19, 1, 31, 4]
[(1, 10), (1, 31)]

That is, [(1, 10), (1, 31)] is the result you are after, 1 being the minimum of the combined values of the first group of indices, 10 the maximum of that same group of values, etc.

Some explanation of key lines:

values = list(x for key in group for x in d[tuple(key)])

This constructs a list of combined values by looping over every pair of key values in group and using them as an index into the dictionary d. However, since key will be an ndarray after the reshaping, it is passed to the tuple() function first, so that the dict is correctly indexed. It loops over the retrieved values and adds each value x to the resulting list.

The solution is put together in a single comprehension:

[
    (min(vals), max(vals)) for vals in (
        list(x for key in grp.reshape(-1, grp.shape[-1]) for x in d[tuple(key)])
        for grp in indices
    )
]

The outer brackets indicate that a list is being constructed. (min(vals), max(vals)) is a tuple of min and max of vals, and vals loops over the inner comprehension. The inner comprehension is a generator (with parentheses instead of brackets) generating the lists for each group in indices, as explained above.

Python相关问答推荐

时间序列分解

如何在箱形图中添加绘制线的传奇?

在Python中处理大量CSV文件中的数据

为什么符号没有按顺序添加?

如何在虚拟Python环境中运行Python程序?

ODE集成中如何终止solve_ivp的无限运行

梯度下降:简化要素集的运行时间比原始要素集长

实现自定义QWidgets作为QTimeEdit的弹出窗口

用渐近模计算含符号的矩阵乘法

在pandas/python中计数嵌套类别

Python—压缩叶 map html作为邮箱附件并通过sendgrid发送

获取git修订版中每个文件的最后修改时间的最有效方法是什么?

Pandas数据框上的滚动平均值,其中平均值的中心基于另一数据框的时间

Regex用于匹配Python中逗号分隔的AWS区域

在任何要保留的字段中添加引号的文件,就像在Pandas 中一样

如何在python tkinter中绑定键盘上的另一个回车?

Scipy.linprog的可行性有问题吗?(A_ub@x0<;=b_ub).all()为True-但是-linprog(np.zeros_like(X0),A_ub=A_ub,b_ub=b_ub)不可行

pyspark where子句可以在不存在的列上工作

对列中的数字进行迭代,得到n次重复开始的第一个行号

`Convert_time_zone`函数用于根据为极点中的每一行指定的时区检索值