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相关问答推荐

AsyncIO 这个任务第二次 await 什么时候发生?

如何让回车符在 Python 3 中使用 input()

从字符串中提取内容的正则表达式,将其与模式 'XX:XX am or pm' 相关联

按时间间隔分组和计数 - Python

使用 eval 时 locals() 字典的奇怪行为

如何使用 pandas 在数据框的列中删除逗号后的数据?

python中的复杂列表比较

如何在 python 脚本中找到所有 *used* 的函数?

在 pygame 中显示的缓冲区不会在 tkinter 中显示

如何从 API 获取纯文本?

使用值列表编写字典时出现 DictWriter 问题

数据框的动态列表

使用子类时类型不匹配

为什么没有 keras.engine 的文档?

使用 python 3.7.13 在 Windows 上的 GPU 上的 Keras

按给定行对 3D 数组进行排序

Python乌龟模块没有响应正在发出的击键

仅在尚未附加项目时附加?

Numpy:ValueError:无法将浮点 NaN 转换为整数(Python)

Selenium - Python - AttributeError:“WebDriver”对象没有属性“find_element_by_name”