2017-01-25 4 views
2

У меня есть numpy 1-мерный массив с n значениями, можно назвать его xdata.Как создать многомерный массив numpy?

Я хотел бы создать многомерный массив numpy, чтобы назвать его xdataMulti таким, что каждое измерение этого массива содержит значения в xdata, которые находятся в определенном диапазоне.

Например позволяет сказать, что

xdata = np.array([-0.879645943,-0.7897614865,-0.7051130178,-0.6108652382,-0.5270894341,...]) 

и что я хочу поставить все значения XData между -0.9 и -0.6 в xdataMulti[:,0] и все значения между -0.6 и 0 в xdataMulti[:,1] и т.д.

Как сделать Я создаю и заполняю xdataMulti (я знаю заранее, сколько диапазонов у меня есть и их конечных точек, но я не знаю, сколько точек xdata в каждом диапазоне, мне нужно пройти через xdata, чтобы узнать)?

+1

Это не совсем то, что NumPy (мульти-) предназначены массивы для сравнения! Длина записей в каждом измерении должна быть одинаковой. – Lagerbaer

+1

Вы описываете список массивов разных размеров. – hpaulj

+0

Да, это список массивов разных размеров. Мне нужно, чтобы каждый был массив numpy, чтобы вызвать функцию scipy, которая принимает только массивы numpy. – user2175783

ответ

2

Если количество диапазонов не слишком велик, вы можете создать их вручную

gm09 = xdata >= -0.9 
gm06 = xdata >= -0.6 
g0 = xdata >= 0 
ranges = [xdata[gm09 & ~gm06], xdata[gm06 & ~g0]] 
result = [f(r) for r in ranges] 

где F является вашей SciPy функции.

Если число ваших диапазонов велико, то вы можете отсортировать ваши данные, а затем использовать searchsorted. Предполагая, что вы границы блоков в отсортированном массиве bnd:

xs = np.sort(xdata) 
xbnd = np.searchsorted(xs, bnd) 
ranges = [xs[l:r] for l, r in zip(xbnd[:-1], xbnd[1:])] 
result = [f(r) for r in ranges] 

Обратите внимание, что это отличается от первого решения в том, что будут рассортированы ваши диапазоны.

Если вам нужно сохранить оригинальный заказ вы можете использовать косвенные сортировки

order = np.argsort(xdata) 
xbnd = np.searchsorted(xdata[order], bnd) 
ordord = [np.sort(order[l:r]) for l, r in zip(xbnd[:-1], xbnd[1:])] 
ranges = [xdata[oo] for oo in ordord] 
result = [f(r) for r in ranges] 
+1

В среднем коде * xs = np.sort (xdata) xbnd = np.searchsorted (xs, bnd) range = [xs [l: r] для l, r в zip (xbnd [: - 1], xbnd [1:])] result = [f (r) для r в диапазонах] * Представьте, что xbnd - [6,18], тогда zip - [(6,18)], а объект диапазонов будет содержать диапазон от 6 и 18 (между 0 и 6 и 18 и последними не выбраны). – JennyToy

+1

@JennyToy Хм, разве это не так? Если xbnd начать с шести означает, что наименьшие шесть значений в xdata находятся ниже самой маленькой границы бункера, поэтому нет бина, в котором они должны находиться, по крайней мере, в терминах исходного Q.Если вы хотите собрать эти выбросы, вы всегда можете сделать что-то вроде xbnd = np.r_ [0, xbnd, len (xdata)] –

1

многомерные массивы должны быть прямоугольными, поэтому, если не все ваши строки/столбцы имеют одинаковую длину, вам не повезло.

Однако есть способы справиться с этим. Одним из способов было бы создать list из arrays:

>>> arr = np.random.random((10)) # using this for values 

>>> # each item in ranges corresponds to the lower and upper border. 
>>> ranges = [(0, 0.3), (0.3, 0.6), (0.6, 1)] 

>>> [arr[(arr >= lower) & (arr < upper)] for lower, upper in ranges] 
[array([ 0.15346374]), 
array([ 0.38144735, 0.45017858, 0.52710788, 0.36339812]), 
array([ 0.79770651, 0.77543868, 0.94824291, 0.87412998, 0.70890894])] 

Это не многомерный массив, просто список массивов, но в зависимости от ваших потребностей, которые могут быть достаточно.

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