2015-08-03 10 views
5

मेरे पास डेटा पॉइंट हैं जो 2 डी सरणी (मैट्रिक्स) के लिए निर्देशांक का प्रतिनिधित्व करते हैं। अंक नियमित रूप से gridded हैं, सिवाय इसके कि डेटा ग्रिड कुछ ग्रिड पदों से गायब हैं।निर्देशांक से 2 डी न्यूम्पी सरणी बनाएं

उदाहरण के लिए, कुछ XYZ डेटा पर विचार करें जो नियमित 0.1 ग्रिड पर आकार (3, 4) के साथ फिट बैठता है। वहाँ अंतराल और लापता अंक हैं, इसलिए वहाँ 5 अंक, और नहीं 12 हैं:

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] 

मैं देखना चाहेंगे क्या इस छवि (पृष्ठभूमि में दिखाया गया है: काले = आधार -0 सूचकांक; ग्रे = मूल्य के बीच तालमेल की रंग = मैट्रिक्स मान; सफेद = गायब)।

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]]  

वहाँ दृष्टिकोण एक 2D सरणी ar वापस जाने के लिए vectorising का एक और अधिक NumPythonic रास्ता नहीं है:

matrix

यहाँ है कि मैं क्या है, जो पाश के लिए एक साथ सहज है है? या लूप के लिए जरूरी है?

उत्तर

7

आप 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

आप एक scipy coo_matrix इस्तेमाल कर सकते हैं के साथ एक पंक्ति में कर सकते हैं। यह आपको निर्देशांक और डेटा से एक स्पैर मैट्रिक्स बनाने की अनुमति देता है। संलग्न लिंक पर उदाहरण देखें।

http://docs.scipy.org/doc/scipy-0.15.1/reference/generated/scipy.sparse.coo_matrix.html

आशा है कि मदद करता है।

1

sparse मैट्रिक्स पहला समाधान जो मन में आया है, लेकिन चूंकि X और Y तैरता हैं, यह थोड़ा जटिल है:

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]]) 

यह अभी भी जरूरत है, एक ही रास्ता या अन्य में, यही निर्देशांक मैच के लिए [0,1,2 ...] इंडेक्स के साथ। मेरी त्वरित धोखा सिर्फ मूल्यों को रैखिक रूप से स्केल करना था। यहां तक ​​कि फ्लोट्स को इनट्स में परिवर्तित करते समय भी मुझे ख्याल रखना पड़ा।

sparse.coo_matrix काम करता है क्योंकि एक विरल मैट्रिक्स को परिभाषित करने की एक प्राकृतिक तरीके (i, j, data) tuples है, जो निश्चित रूप से I, J, Data सूचियों या सरणियों के लिए अनुवाद किया जा सकता है।

मुझे हिस्टोरोग्राम समाधान पसंद है, भले ही मेरे पास इसका उपयोग करने का मौका न हो।

2

आप X और Y का उपयोग बनाने के लिए एक्स-वाई एक 0.1 स्थान दिया गया है ग्रिड min to max of X और min to max of Y और फिर डालने Z's उन विशिष्ट स्थिति में से बढ़ाने पर निर्देशांक कर सकते हैं। Xr और Yr प्राप्त करने के लिए यह linspace का उपयोग करने से बच जाएगा और यह काफी कुशल होना चाहिए।

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 

रनटाइम परीक्षण - -

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 
-

यह खंड प्रदर्शन के लिए अन्य np.histogram2d based solution के खिलाफ indexing-based दृष्टिकोण की तुलना यहाँ कार्यान्वयन है

संबंधित मुद्दे