2016-02-15 8 views
0

У меня 3 массива:Использование numpy.tile повторить 2D массивы

e = np.array(range(3,100)) 
dRdE = np.load('arr_25.npy') 

NPY файл содержит массив со случайными значениями, но имеет ту же длину, что и е. Затем я беру внешний продукт dRdE с другим массивом.

s = np.array(range(1,100)) 
dRdE = np.outer(s, dRdE) 

И вот dRdE сейчас 2D.

Я хочу, чтобы e повторяло количество раз каждого элемента в dRdE. Я мог бы использовать dRdE раньше, когда он был 1D и такой же длины, как и с помощью повтора numpy. Код, который я имел в своем распоряжении был:

earray = np.repeat(e, dRdE) 

Но поскольку dRdE больше не 1D я думал, что я мог бы быть в состоянии использовать np.tile, но я точно не знаю, как.

Контекст может помочь, поэтому у меня есть переменная от 3keV до 100keV, и у меня есть массив, содержащий количество событий (dRdE) для каждой энергии между этим диапазоном. Но теперь я хочу представить третью переменную, которая является лишь некоторые фактор dRdE от 1 до 100. Так, например, если:

dRdE= [1,2,1,2..],[2,4,2,4..],[3,6,3,6] 

Я хочу:

earray=([3,4,4,5,6,6,...],[3,3,4,4,4,4,5,5,6,6,6,6,...],[3,3,3,4...]) 

Любая помощь будет оценен по достоинству!

+0

Подрезы в 'earray' отличаются по длине?Если это так, то вам, вероятно, просто придется применять 'repeat' row by row. 'tile' для шаблонов, которые применяются по строкам и/или столбцам, - обычный шаблон плитки, а не мозаика. – hpaulj

+0

Да, они, к сожалению, так работают, если бы подсписки были одинаковой длины? –

ответ

0

Я спросил о подстроках переменной длины, потому что это явный индикатор того, что требуется какая-то итерация. Существует не так много операций numpy, которые создают список или кортеж различных массивов длины.

Означает в tile немного больше (это не то, что я использую каждый день), я не думаю, что это вообще помогает. Его reps - одно значение на размер, не на элемент.

Но давайте исследовать repeat.

In [73]: vals=[[1,2,3,4],[11,12,13,14],[21,22,23,24]] 
In [74]: reps=[[1,2,1,2],[2,3,2,4],[3,6,3,6]] 
In [75]: valA=np.array(vals) 
In [76]: repA=np.array(reps) 

Итерационное решение:

In [77]: [np.repeat(v,r) for v,r in zip(valA,repA)] 
Out[77]: 
[array([1, 2, 2, 3, 4, 4]), 
array([11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 14]), 
array([21, 21, 21, 22, 22, 22, 22, 22, 22, 23, 23, 23, 24, 24, 24, 24, 24, 
     24])] 

Мы также могли бы применить repeat разы

In [78]: np.repeat(valA.flat,repA.flat) 
Out[78]: 
array([ 1, 2, 2, 3, 4, 4, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 14, 
     21, 21, 21, 22, 22, 22, 22, 22, 22, 23, 23, 23, 24, 24, 24, 24, 24, 
     24]) 

Теперь, если только мы могли бы разделить этот массив в 3-х массивы, каждый из элементов 6,11,18 длинный.

In [79]: [len(np.repeat(v,r)) for v,r in zip(valA,repA)] 
Out[79]: [6, 11, 18] 

In [80]: np.split(np.repeat(valA.flat,repA.flat),[6,17]) 
Out[80]: 
[array([1, 2, 2, 3, 4, 4]), 
array([11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 14]), 
array([21, 21, 21, 22, 22, 22, 22, 22, 22, 23, 23, 23, 24, 24, 24, 24, 24, 
     24])] 

Я уверен, что существует более быстрый способ расчета [6,17] списка.

Но когда я делаю timeit, я нахожу, что понимание списка выполняется быстрее (10x), чем сплит. Еще быстрее, чем один повтор. Сроки будут отличаться в зависимости от больших массивов, но обойти список итераций не представляется многообещающим.

+0

Можно ли записать его так, что 'vals = [[500, 512, 502, ..., 600]]' где vals - это всего лишь 1D-массив, а не реквизиты и reps = [[1], [2], [ 3], [4] ...., [10]] ', затем используя повтор для выделения массива с подсписками' [[500, 512, 502, ....], [500, 500, 512, 50, 502 ....], ..... .] ' –