如何有效地访问另一个可迭代的Python可迭代索引

时间:2017-10-19 23:18:08

标签: python arrays list loops numpy

我有一个列表X和一个列表Y,其中有一些混洗索引。

X = ['a', 'b', 'c', 'd','e']
Y = [ 1 ,  3 ,  4 ,  0 , 2 ]

我希望有一个新列表Z,以便

Z = [ X[i] for i in Y ] = ['b', 'd', 'e', 'a', 'c']

问题在于,对于如此大的arrays,我必须多次这样做。有什么比循环列表更有效的方法?

注意: numpy解决方案是折旧的!

2 个答案:

答案 0 :(得分:5)

由于operator.itemgetter接受多个索引,因此一个解决方案是:

>>> import operator
>>> operator.itemgetter(*Y)(X)
('b', 'd', 'e', 'a', 'c')

有效的(在评论中公布)将通过numpy的数组索引:

np.array(X)[Y]

如果XY转换为numpy.array一次(提前使用)并多次使用。

性能测试

1k元素列表(Y)索引1M个元素(X)。

# setup
import random
import numpy as np
X = [random.randint(0,100) for i in range(1000000)]
Y = [random.randint(0,1000000) for i in range(1000)]

1)列表理解~34μs

%timeit [X[i] for i in Y]
10000 loops, best of 3: 34 µs per loop

2)itemgetter~16.6μs

%timeit operator.itemgetter(*Y)(X)
100000 loops, best of 3: 16.6 µs per loop

3)numpy,数组在飞行时转换~31.6ms⇒最慢

%timeit np.array(X)[Y]
10 loops, best of 3: 31.6 ms per loop

4)numpy,阵列预转换~1.72μs⇒最快

x = np.array(X)
y = np.array(Y)
%timeit x[y]
1000000 loops, best of 3: 1.72 µs per loop

答案 1 :(得分:2)

将列表转换为NumPy数组,并使用第二个作为第一个列表的索引:

library(tidyverse)

GEE <- tribble(
  ~trait, ~beta, ~se, ~p, ~analysis, ~signif,
  "trait1", 0.078, 0.01, 9.0e-13, "group1", 1,
  "trait2", 0.076, 0.01, 1.7e-11, "group1", 1,
  "trait3", 0.063, 0.01, 1.8e-08, "group1", 1,
  "trait4", 0.013, 0.01, .06, "group1", 0,
  "trait5", 0.018, 0.01, .54, "group1", 0,
  "trait6", -0.014, 0.01, .64, "group1", 0
  )

GEE %>% 
  ggplot(aes(y = beta, x = reorder(trait, beta)), group = analysis) +
  geom_point(aes(color = analysis)) +
  geom_errorbar(aes(ymin = beta - 2 * se,
                    ymax = beta + 2 * se,
                    color = analysis,
                    width = 0.2),
                position = position_dodge(0.9)) +
  geom_point(data = GEE[GEE$signif == 1, ],
             color="red",
             shape = "*", 
             size=12, 
             show.legend = F) +
  theme_light() +
  coord_flip()