3

假设我有一本字典,里面有my_dict几个 2D numpy 数组(每个键一个)。所有这些数组都具有相同的维度。假设我们有 1000 个这样的数组。

我想获得一个字典top_per_location,给定一个 tuple (x,y)top_per_location[(x,y)]返回my_dict按 的值排序的键元组my_dict[key][x,y]

对此的蛮力方法(即为[x,y]dict中的每个键显式循环)似乎非常慢。关于如何在不显式循环的情况下解决这个问题的任何想法?

到目前为止,我有:

# xsize and ysize are the 
grid_x, grid_y = np.mgrid[0:xsize, 0:ysize]
top_per_location = dict()
for x,y in zip(grid_x.ravel(), grid.y_ravel):
    values = dict()
    for key in my_dict:
      values[key] = my_dict[key][x,y]
    # We would then sort values[key]
    # and store the sorted keys in top_per_location[(x,y)]

循环遍历每个键,这需要很长时间xsize=ysize=100

4

2 回答 2

2

如果您追求的是速度,那么您最好从不同的数据结构开始。制作一个 3D 数据数组n*y*x和一个 1D 键数组,键的索引与数据数组的 n_index 匹配。这样我们就可以向量化了。

抽象意义上的:

import numpy

a = numpy.arange(10 * 5 * 5).reshape((10, 5, 5))
numpy.random.shuffle(a)
b = numpy.array(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])
print b[numpy.argsort(a[:, 3, 3])]

应用您当前的数据结构:

# Simulating my_dict
y_dim = 5
x_dim = 6
my_dict = {chr(i + 97): numpy.random.randn(y_dim, x_dim) for i in xrange(10)}

# To initially convert your data structure
new_my_dict = {}
keys = numpy.zeros(len(my_dict), dtype=numpy.str)
data = numpy.zeros((len(my_dict), y_dim, x_dim))
for i, (key, value) in enumerate(my_dict.iteritems()):
    keys[i] = key
    data[i, :, :] = value
    new_my_dict[key] = i


# the sorting function
def top_per_location(y, x):
    return keys[numpy.argsort(data[:, y, x])]

def get_data(key):
    index = new_my_dict.get(key)
    if index is not None:
        return data[index]
    else:
        raise KeyError('{} not in data!'.format(key))

def add_data(key, new_data):
    global data, keys
    if key in new_my_dict:
        data[new_my_dict[key]] = new_data
    else:
        new_my_dict[key] = data.shape[0] + 1
        keys = numpy.append(keys, key)
        data = numpy.concatenate((data, numpy.expand_dims(new_data, axis=0)))

print(top_per_location(3, 3))
add_data('frog', numpy.random.randn(y_dim, x_dim))
add_data('fish', numpy.random.randn(y_dim, x_dim))
print(get_data('frog'))

如果您需要进行大量查找,您仍然可以拥有您的字典,但使其成为一个简单的 {key: index} 字典,索引指向数据的 n_dimension。

于 2013-10-09T03:37:19.510 回答
1

函数而不是字典怎么样?

def top_per_location(xy):
    return tuple(sorted(my_dict.keys(), key=lambda key:my_dict[key][xy]))

示例用法:

top_per_location((2, 3))

这应该返回按每个数组中坐标 (x, y) 处的值排序的键元组。

这是否比您的字典解决方案更有效取决于您使用字典的频率与创建字典的频率。

注意:假设my_dict可以从函数命名空间访问。如果不是,您需要做一些事情,例如my_dict作为参数传入。

于 2013-10-09T02:54:47.847 回答