2015-08-03 26 views
5

2B dizi (matris) için koordinatları temsil eden veri noktalarına sahibim. Noktalar düzenli olarak ızgaralıdır, ancak bazı ızgara konumlarından veri noktaları eksiktir. Örneğin, düzenli bir 0,1 ızgaraya uyan XYZ verilerini bazı şekillerde dikkate alın (3, 4). boşluklar ve eksiklikler vardır, yani 5 puan, ve 12 vardır: görmek istiyorum ne2B dizi dizisini koordinatlardan yapın

import numpy as np 
X = np.array([0.4, 0.5, 0.4, 0.4, 0.7]) 
Y = np.array([1.0, 1.0, 1.1, 1.2, 1.2]) 
Z = np.array([3.3, 2.5, 3.6, 3.8, 1.8]) 
# Evaluate the regular grid dimension values 
Xr = np.linspace(X.min(), X.max(), np.round((X.max() - X.min())/np.diff(np.unique(X)).min()) + 1) 
Yr = np.linspace(Y.min(), Y.max(), np.round((Y.max() - Y.min())/np.diff(np.unique(Y)).min()) + 1) 
print('Xr={0}; Yr={1}'.format(Xr, Yr)) 
# Xr=[ 0.4 0.5 0.6 0.7]; Yr=[ 1. 1.1 1.2] 

Bu resmi (arka gösterilmiştir: siyah = baz-0 indeksi; gri = koordinat değeri; renk = matris değeri; beyaz = eksik). 2D dizi ar dönmek yaklaşım vectorising daha NumPythonic yolu var mı

ar = np.ma.array(np.zeros((len(Yr), len(Xr)), dtype=Z.dtype), mask=True) 
for x, y, z in zip(X, Y, Z): 
    j = (np.abs(Xr - x)).argmin() 
    i = (np.abs(Yr - y)).argmin() 
    ar[i, j] = z 
print(ar) 
# [[3.3 2.5 -- --] 
# [3.6 -- -- --] 
# [3.8 -- -- 1.8]]  

: Burada

matrix

Ben for döngüsü ile sezgisel olan ne var? Veya for döngüsü gerekli mi?

cevap

7

Sen np.histogram2d

data = np.histogram2d(Y, X, bins=[len(Yr),len(Xr)], weights=Z) 
print(data[0]) 
[[ 3.3 2.5 0. 0. ] 
[ 3.6 0. 0. 0. ] 
[ 3.8 0. 0. 1.8]] 
1

sparse matris akla gelen ilk çözüm, ancak X ve Y yüzer olduğundan, biraz dağınık: O koordinatları eşleştirmek için bir yol ya da diğer,

In [624]: I=((X-.4)*10).round().astype(int) 
In [625]: J=((Y-1)*10).round().astype(int) 
In [626]: I,J 
Out[626]: (array([0, 1, 0, 0, 3]), array([0, 0, 1, 2, 2])) 

In [627]: sparse.coo_matrix((Z,(J,I))).A 
Out[627]: 
array([[ 3.3, 2.5, 0. , 0. ], 
     [ 3.6, 0. , 0. , 0. ], 
     [ 3.8, 0. , 0. , 1.8]]) 

Hala ihtiyacı [0,1,2 ...] indeksleri ile. Hızlı aldatmam, değerleri lineer olarak ölçeklendirmekti. Öyle olsa bile, yüzerleri ints'e dönüştürürken dikkat etmeliydim.

sparse.coo_matrix çalışmaları seyrek bir matris oluşturan doğal bir yolu, elbette I, J, Data listeleri veya diziler tercüme edilebilir (i, j, data) küpe ile olduğu için.

Kullanmak için fırsatım olmasa da historgram çözümünü tercih ediyorum.

2

, X-Y, o belirli pozisyonlar içine sokulması min to max of X ve min to max of Y ve Z's uzanan bir 0.1 aralıklı bir ızgara üzerinde koordinatları oluşturmak X ve Y kullanabilir. Bu, Xr ve Yr'u almak için linspace'u kullanmaktan kaçınacaktır ve bu nedenle oldukça verimli olması gerekir.

def indexing_based(X,Y,Z): 
    # Convert X's and Y's to indices on a 0.1 spaced grid 
    X_int = np.round((X*10)).astype(int) 
    Y_int = np.round((Y*10)).astype(int) 
    X_idx = X_int - X_int.min() 
    Y_idx = Y_int - Y_int.min() 

    # Setup output array and index it with X_idx & Y_idx to set those as Z 
    out = np.zeros((Y_idx.max()+1,X_idx.max()+1)) 
    out[Y_idx,X_idx] = Z 

    return out 

Süre testleri - -

In [132]: # Create unique couples X-Y (as needed to work with histogram2d) 
    ...: data = np.random.randint(0,1000,(5000,2)) 
    ...: data1 = data[np.lexsort(data.T),:] 
    ...: mask = ~np.all(np.diff(data1,axis=0)==0,axis=1) 
    ...: data2 = data1[np.append([True],mask)] 
    ...: 
    ...: X = (data2[:,0]).astype(float)/10 
    ...: Y = (data2[:,1]).astype(float)/10 
    ...: Z = np.random.randint(0,1000,(X.size)) 
    ...: 

In [133]: def histogram_based(X,Y,Z): # From other np.histogram2d based solution 
    ...: Xr = np.linspace(X.min(), X.max(), np.round((X.max() - X.min())/np.diff(np.unique(X)).min()) + 1) 
    ...: Yr = np.linspace(Y.min(), Y.max(), np.round((Y.max() - Y.min())/np.diff(np.unique(Y)).min()) + 1) 
    ...: data = np.histogram2d(Y, X, bins=[len(Yr),len(Xr)], weights=Z) 
    ...: return data[0] 
    ...: 

In [134]: %timeit histogram_based(X,Y,Z) 
10 loops, best of 3: 22.8 ms per loop 

In [135]: %timeit indexing_based(X,Y,Z) 
100 loops, best of 3: 2.11 ms per loop 
-

Bu bölüm performansı için diğer np.histogram2d based solution karşı indexing-based yaklaşımı karşılaştırmak İşte uygulanması bulunuyor