我有一个非常简单的操作,涉及两个不那么大的数组:
Map<String, Image> imageRepository = new HashMap<>(); // to be filled
PickUpItem createItem(String type, int x, int y) {
Image itemImage = imageRepository.getOrDefault(type, yourDefaultImg);
return new PickUpItem(itemImage, x, y);
}
public void spawnPickUpItem(String type, int x, int y) {
PickUpItem pickUpItem = createItem(String type, int x, int y);
// further logic . . .
}
位置的每个元素i
j
和第四个数组(与第二个数组相同的长度)的位置i
中存储从第三个数组(与第一个数组相同的长度)中提取的浮点数下面的j
块可以工作,但是对于不是那么大的数组(> 10000)来说,非常变慢。
可以更快地实现此实现吗?
for
答案 0 :(得分:1)
为捍卫我的方法,以下是权威性的实施方式:
import itertools as it
def pp():
la,lb = len(ids_a),len(ids_b)
ids = np.fromiter(it.chain(ids_a,ids_b),'<S6',la+lb)
unq,inv = np.unique(ids,return_inverse=True)
vals = np.empty(la,vals_in_a.dtype)
vals[inv[:la]] = vals_in_a
return vals[inv[la:]]
(juanpa()==pp()).all()
# True
timeit(juanpa,number=100)
# 3.1373191522434354
timeit(pp,number=100)
# 2.5256317732855678
也就是说,@ juanpa.arrivillaga的建议也可以更好地实现:
import operator as op
def ja():
return op.itemgetter(*ids_b)(dict(zip(ids_a,vals_in_a)))
(ja()==pp()).all()
# True
timeit(ja,number=100)
# 2.015202699229121
答案 1 :(得分:0)
我尝试了juanpa.arrivillaga和Paul Panzer的方法。第一个是迄今为止最快的。这也是最简单的。第二种方法比我最初的方法要快,但比第一种方法要慢得多。它还有一个缺点,该行vals[inv_a] = vals_in_a
将浮点数存储到U5
数组中,从而将它们转换为字符串。可以在结尾将其转换回浮点数,但是我会丢失数字(除非我当然缺少明显的东西。
以下是实现:
def juanpa():
dict_ids_b = {_: i for i, _ in enumerate(ids_b)}
for i, id_a in enumerate(ids_a):
try:
vals_in_b[dict_ids_b[id_a]] = vals_in_a[i]
except KeyError:
pass
return vals_in_b
def Paul():
# 1) concatenate ids_a and ids_b
ids_ab = ids_a + ids_b
# 2) apply np.unique with keyword return_inverse=True
vals, idxs = np.unique(ids_ab, return_inverse=True)
# 3) split the inverse into inv_a and inv_b
inv_a, inv_b = idxs[:len(ids_a)], idxs[len(ids_a):]
# 4) map the values to match the order of uniques: vals[inv_a] = vals_in_a
vals[inv_a] = vals_in_a
# 5) use inv_b to pick the correct values: result = vals[inv_b]
vals_in_b = vals[inv_b].astype(float)
return vals_in_b