2015-05-28 2 views
1

У меня есть таблица значений сохраняются в список списков, как:Построить массив из другого массива и таблицы значений (Python)

A = [ [a[1],b[1],c[1]], 
     [a[2],b[2],c[2]], 
     ... 

     [a[m],b[m],c[m]]] 

with 
a[i] < b[1] 
b[i] < a[i+1] 
0 < c[i] < 1 

и Numpy массив, такие как:

X = [x[1], x[2], ..., x[n]] 

Мне нужно создать массив

Y = [y[1], y[2], ..., y[n]] 

, где каждое значение Y будет соответствовать

for i in [1,2, ..., n]: 
    for k in [1,2, ..., m]: 
    if a[k] < x[i] < b[k]: 
     y[i] = c[k] 
    else: 
     y[i] = 1 

Обращаем внимание, что X и Y имеют одинаковую длину, но А совершенно разные. Y может принимать любое значение в третьем столбце A (c [k] для k = 1,2, ... m), если выполняется [k] < x [i] < b [k] (для k = 1,2, ... m и для i = 1,2, ... n).

В реальных случаях я работаю, п = 6789 и т = 6172.

я мог бы сделать проверку с помощью вложенной «для» цикла, но это очень медленно. Каков самый быстрый способ сделать это? что, если X и Y, где 2D-массивы numpy?

SAMPLE DATA:

a = [10, 20, 30, 40, 50, 60, 70, 80, 90] 
b = [11, 21, 31, 41, 51, 61, 71, 81, 91] 
c = [ 0.917, 0.572, 0.993 , 0.131, 0.44, 0.252 , 0.005, 0.375, 0.341] 

A = A = [[d,e,f] for d,e,f in zip(a,b,c)] 

X = [1, 4, 10.2, 20.5, 25, 32, 41.3, 50.5, 73] 

ОЖИДАЕМЫЕ РЕЗУЛЬТАТЫ:

Y = [1, 1, 0.993, 0.132, 1, 1, 1, 0.375, 1 ] 
+0

Почему бы вы сделали 'почтовый ([1,2, ..., п], [1,2, ..., т])'? Кажется вероятным, что это не делает то, что вы думаете. – user2357112

+0

@ user2357112: вы действительно правы, я обновил вопрос. Благодарю. – jorgehumberto

+0

Новая версия по-прежнему выглядит неправильно. Каждое значение 'y [i]' перезаписывается снова и снова. – user2357112

ответ

1

Подход № 1: Используя сравнение перебором с broadcasting -

import numpy as np 

# Convert to numpy arrays 
A_arr = np.array(A) 
X_arr = np.array(X) 

# Mask that represents "if a[k] < x[i] < b[k]:" for all i,k 
mask = (A_arr[:,None,0]<X_arr) & (X_arr<A_arr[:,None,1]) 

# Get indices where the mask has 1s, i.e. the conditionals were satisfied 
_,C = np.where(mask) 

# Setup output numpy array and set values in it from third column of A 
# that has conditionals satisfied for specific indices 
Y = np.ones_like(X_arr) 
Y[C] = A_arr[C,2] 

подход # 2: Основываясь на биннинга с np.searchsorted -

import numpy as np 

# Convert A to 2D numpy array 
A_arr = np.asarray(A) 

# Setup intervals for binning later on 
intv = A_arr[:,:2].ravel() 

# Perform binning & get interval & grouped indices for each X 
intv_idx = np.searchsorted(intv, X, side='right') 
grp_intv_idx = np.floor(intv_idx/2).astype(int) 

# Get mask of valid indices, i.e. X elements are within grouped intervals 
mask = np.fmod(intv_idx,2)==1 

# Setup output array 
Y = np.ones(len(X)) 

# Extract col-3 elements with grouped indices and valid ones from mask 
Y[mask] = A_arr[:,2][grp_intv_idx[mask]] 

# Remove (set to 1's) elements that fall exactly on bin boundaries 
Y[np.in1d(X,intv)] = 1 

Пожалуйста, обратите внимание, что если вам нужно вывод в виде списка, вы можете преобразовать массив numpy в список с таким вызовом - Y.tolist().


Пример запуска -

In [480]: A 
Out[480]: 
[[139.0, 355.0, 0.5047342078960846], 
[419.0, 476.0, 0.3593886192040009], 
[580.0, 733.0, 0.3137694021600973]] 

In [481]: X 
Out[481]: [555, 689, 387, 617, 151, 149, 452] 

In [482]: Y 
Out[482]: 
array([ 1.  , 0.3137694 , 1.  , 0.3137694 , 0.50473421, 
     0.50473421, 0.35938862]) 
+0

Отлично, спасибо! – jorgehumberto

0

С 1-й массивов, это не так уж плохо:

a,b,c = np.array(A).T 
mask = (a<x) & (x<b) 
y = np.ones_like(x) 
y[mask] = c[mask] 

Если x и y являются более объемными, тогда ваша матрица A также должна быть больше. Однако основная концепция работает одинаково.

+0

Прошу прощения, вы заставили меня понять, что объяснение неверно. A имеет длину «m», но X и Y имеют длину «n». Y может принимать любое значение в третьем столбце A. Я обновил вопрос, чтобы сделать его более понятным. – jorgehumberto

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