2015-01-14 4 views
-1

Я использую Python с numpy, scipy, matplotlib.Яркость (или изображение) с строками, соответствующими массивам переменной длины

У меня есть два списка, содержащие массивы различной длины, которые для конкретности я назову x и y и скажу, что они выглядят (фактические массивы имеют порядок ~ 1000 элементов в длину, а фактические списки имеют порядок ~ 10s до 100s ~ массивов):

x = [ 
    np.array([0, 1, 2, 3, 4]), 
    np.array([0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4]), 
    np.array([0, 2 ,4]) 
] 
y = [ 
    np.array([0, 0, 1, 0, 0]), 
    np.array([1, 0.75, 0.5, 0.25, 0.0, 0.25, 0.5, 0.75, 1]), 
    np.array([0, 1, 0,]) 
] 

каждого х-массив отсортирован, и каждый из Y-массив, упорядоченный по соответствующему х массиву, так Len (х [г]) == Len (y [i]) всегда True, а x [i] [j] всегда соответствует y [i] [j]. Каждый x-массив находится в диапазоне между теми же двумя значениями (например, 0 и 4 в приведенном выше примере).

Я хочу сделать сюжет или сохранить изображение (если возможно, я хочу знать, как это сделать), где i-я строка равна y [i] vs. x [i], с яркостью, соответствующей y -стоимость.

Так, например, в приведенном выше примере:

  • Для всего участка оси х будет идти от 0 до 4 (если я сохранить изображение вместо того чтобы сделать сюжет, то я не волнуюсь о том, что я все равно явно имеет значения х на оси, но я просто знаю, что значения у каждой строки соответствуют значениям х, идущим от 0 до 4).
  • Первый ряд будет иметь среднюю пятую часть строки белого цвета, а остальную часть строки - черную.
  • 2-й ряд будет разделен на восьмерки, с серединой ряда черными, а два края - белыми, остальные оттенки серого.
  • Третий ряд будет разделен на треть, а средняя третья строка будет белой и две краевые части черной строки.

Я уверен, что я мог бы сделать это легко, если Python или NumPy имеет какие-либо функции растягивания массива, так что я мог бы нормализовать длины всех массивов в х и у, или если Matplotlib просто имеет встроенную в функции для такого типа сюжета. Но я не знаю, существует ли это.

Кто-нибудь знает, как это сделать (или, если на то пошло, что этот сюжет будет называться)?

Большое спасибо за любую помощь. Пожалуйста, дайте мне знать, если мой вопрос неясен.

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

x = [ 
    np.array([0, 0, 1, 1, 2, 3, 3, 4, 4]), 
    np.array([0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4]), 
    np.array([0,0,0,2,2,2,4,4,4]) 
] 
y = [ 
    np.array([0, 0, 0, 0, 1, 0, 0, 0, 0]), 
    np.array([1, 0.75, 0.5, 0.25,0, 0 .25,0 .5, 0.75, 1]), 
    np.array([0, 0, 0, 1, 1, 1, 0, 0, 0]) 
] 

И сюжет или изображение будут выглядеть примерно так, как будто это будет изображение версии y (я не могу опубликовать изображение без 10 очков репутации).

+0

'Я уверен, что я мог бы сделать это легко, если Python или numpy имеют любые функции растяжения. Вы посмотрели документацию? Первый результат google, который я вижу для «pad numpy array», таков: http: //docs.scipy.org/doc/numpy/reference/generated/numpy.pad.html –

+0

Хм, я не думаю, что это то, m look for - я мог бы сделать все массивы одинаковой длины, но мне нужно сделать это таким образом, чтобы значения в массиве «разбросаны» через удлиненный массив, например [0,1, 2,3,4] -> [0,0,1,2,2,3,3,4,4]. Так что растянуть, а не площадку. Я искал несколько вещей, таких как «растягивая массив numpy», но не совсем нашел то, что искал. – user3558855

+0

Почему бы вам не включить примеры ваших желаемых финальных массивов и пример такого сюжета, который вы хотели бы видеть? –

ответ

1

Вы можете использовать interp1d с kind="nearest". (Использование «ближайшего» даст шаги на границах и будет выглядеть как расширение, но без необходимости делать это явно, а также сделать разумное приближение к тому, что вы хотите, если ваши длины точно не делятся по мере необходимости.) Это дать что-то вроде этого:

enter image description here

import numpy as np 
from scipy import interpolate 
import matplotlib.pyplot as plt 
import matplotlib.cm as cm 


x = [ 
    np.array([0, 1., 2, 3, 4]), 
    np.array([0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4]), 
    np.array([0, 2., 4]) 
] 
y = [ 
    np.array([0, 0, 1., 0, 0]), 
    np.array([1, 0.75, 0.5, 0.25, .25, 0, .5, 0.75, 1]), 
    np.array([0, 1., 0,]) 
] 

N = 30 
xd = np.linspace(0, 4, 30) 

data = np.zeros((len(x), N), dtype=np.float) 
print data.shape 

for i in range(len(x)): 
    xi, yi = x[i], y[i] 
    f = interpolate.interp1d(x[i], y[i], kind="nearest") 
    data[i] = f(xd) 

fig, ax = plt.subplots() 
i = ax.imshow(data, cmap=cm.gray, interpolation='nearest') 
#fig.colorbar(i) 

plt.show() 

Поскольку х-измерение выхода должно быть целым числом, вам нужно будет иметь номер, который был делится на все или ваши длины. Это могут быть большие нечетные числа (45 в этом случае, хотя я использовал 30 в качестве приближения в приведенном выше примере). Полностью обобщаемый подход состоял бы в том, чтобы построить график из патчей, хотя это было бы гораздо более сложной задачей.

+0

Да, я думаю, что это и подход jme - это разные вещи Я ищу. Я поиграю с этим и посмотрю, смогу ли я заставить его работать, спасибо! – user3558855

+0

@ user3558855: Есть много способов сделать это, и то, что я предложил, является самым простым, что я знаю. Недостатком является то, что «ближайший» Scipy может быть не совсем тем, что вы собираетесь делать. Если вам это не нравится, вам придется манипулировать им более прямо, но если вы спросите об этом здесь, вам нужно быть более конкретным относительно алгоритма, который вы хотите использовать. (Хотя, если это то, что вы хотите использовать, пожалуйста, примите ответ, чтобы мы все это знали.) – tom10

+1

interp1d оказался идеальной функцией. Поскольку некоторые из моих массивов были длинными (от 100 до 1000 с), я пропустил наименее распространенную множественную часть и просто установил длину в длину самого длинного массива. Еще раз спасибо! – user3558855

0

Один из подходов состоит в использовании numpy.repeat, который повторяет каждый элемент массива 1-го числа определенное количество раз. Например:

>>> np.repeat([1,2,3,4], 3) 
array([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]) 

Идея заключается в том, чтобы найти наименьшее общее кратное длин всех списков, а затем использовать np.repeat на каждого, чтобы «растянуть» массивов общей длины.

В целом, можно интерполировать значения массивов, например, линейно, используя scipy.interpolate.interp1d:

from scipy.interpolate import interp1d 
import numpy as np 

x = np.array([0, 1, 2, 3, 4]) 
y = np.array([0, 0, 1, 0, 0]) 

f = interp1d(x,y) 
print f(np.linspace(0,4,10)) 

который печатает:

[ 0.   0.   0.   0.33333333 0.77777778 0.77777778 
    0.33333333 0.   0.   0.  ] 

 Смежные вопросы

  • Нет связанных вопросов^_^