2015-08-17 12 views
7

के आधार पर मैं एक numpy सरणी जो 4-आयामी वैक्टर जो इस प्रारूप (एक्स, वाई, जेड, डब्ल्यू)सबसे बड़ा मान

सरणी के आकार है 4 x एन राशि धारण एक numpy सरणी फ़िल्टर अब, मेरे पास डेटा है जहां मेरे पास (x, y, z) स्थानिक स्थान हैं और डब्ल्यू इस स्थान पर कुछ विशेष माप रखता है। अब, एक (x, y, z) स्थिति (फ्लोट के रूप में मापा गया) से जुड़े कई माप हो सकते हैं।

मैं क्या करना चाहता हूं सरणी फ़िल्टर करना है, ताकि मुझे एक नई सरणी मिल सके जहां मुझे अधिकतम (x, y, z) स्थिति के साथ अधिकतम माप मिलता है।

तो अगर मेरे डेटा की तरह है:

x, y, z, w1 
x, y, z, w2 
x, y, z, w3 

जहां w1 W2 और W3 से अधिक है, फ़िल्टर किए गए डेटा होगा:

x, y, z, w1 

तो अधिक वस्तुतः, कहते हैं कि मैं की तरह डेटा है:

[[ 0.7732126 0.48649481 0.29771819 0.91622924] 
[ 0.7732126 0.48649481 0.29771819 1.91622924] 
[ 0.58294263 0.32025559 0.6925856 0.0524125 ] 
[ 0.58294263 0.32025559 0.6925856 0.05 ] 
[ 0.58294263 0.32025559 0.6925856 1.7 ] 
[ 0.3239913 0.7786444 0.41692853 0.10467392] 
[ 0.12080023 0.74853649 0.15356663 0.4505753 ] 
[ 0.13536096 0.60319054 0.82018125 0.10445047] 
[ 0.1877724 0.96060999 0.39697999 0.59078612]] 

यह लौटना चाहिए

[[ 0.7732126 0.48649481 0.29771819 1.91622924] 
[ 0.58294263 0.32025559 0.6925856 1.7 ] 
[ 0.3239913 0.7786444 0.41692853 0.10467392] 
[ 0.12080023 0.74853649 0.15356663 0.4505753 ] 
[ 0.13536096 0.60319054 0.82018125 0.10445047] 
[ 0.1877724 0.96060999 0.39697999 0.59078612]] 
+0

ही (एक्स, वाई, जेड) पद के लिए प्रविष्टियां हमेशा लगातार हो जाएगा, अपने नमूना डेटा के रूप में , या वे बिखरे हुए होंगे? अभ्यास में आपके पास कितनी प्रविष्टियां होंगी? – jme

+0

दुर्भाग्यवश वे बिखरे हुए हो सकते हैं। वे कभी भी 4 से अधिक नहीं होंगे। इस सौभाग्य से प्रदर्शन महत्वपूर्ण नहीं है। – Luca

+5

एफवाईआई: इसे "ग्रुप-बाय" ऑपरेशन (सीएफ। Http://pandas.pydata.org/pandas-docs/stable/groupby.html) के रूप में जाना जाता है। आप पहले तीन कॉलम द्वारा समूहित कर रहे हैं, और उसके बाद समूहों को अधिकतम फ़ंक्शन लागू कर रहे हैं। पांडा (http://pandas.pydata.org/) जैसी लाइब्रेरी के साथ यह करना बहुत आसान है। –

उत्तर

3

यह जटिल है, लेकिन यह शायद के रूप में अच्छा के रूप में आप numpy केवल का उपयोग कर पाने के लिए जा रहे हैं ...

सबसे पहले, हम का उपयोग करें lexsort सभी प्रविष्टियों को एक ही निर्देशांक के साथ एक साथ रखने के लिए।

>>> perm = np.lexsort(a[:, 3::-1].T) 
>>> a[perm] 
array([[ 0.12080023, 0.74853649, 0.15356663, 0.4505753 ], 
     [ 0.7732126 , 0.48649481, 0.29771819, 0.91622924], 
     [ 0.7732126 , 0.48649481, 0.29771819, 1.91622924], 
     [ 0.1877724 , 0.96060999, 0.39697999, 0.59078612], 
     [ 0.3239913 , 0.7786444 , 0.41692853, 0.10467392], 
     [ 0.58294263, 0.32025559, 0.6925856 , 0.0524125 ], 
     [ 0.58294263, 0.32025559, 0.6925856 , 0.05  ], 
     [ 0.58294263, 0.32025559, 0.6925856 , 1.7  ], 
     [ 0.13536096, 0.60319054, 0.82018125, 0.10445047]]) 

ध्यान दें कि अक्ष उलट कर, हम x द्वारा छँटाई कर रहे हैं, y के साथ संबंधों को तोड़ने तो z, तो w: a अपने नमूना सरणी जा रहा है।

>>> a_sorted = a[perm] 
>>> last = np.concatenate((np.all(a_sorted[:-1, :3] != a_sorted[1:, :3], axis=1), 
          [True])) 
>>> a_unique_max = a_sorted[last] 
>>> a_unique_max 
array([[ 0.12080023, 0.74853649, 0.15356663, 0.4505753 ], 
     [ 0.13536096, 0.60319054, 0.82018125, 0.10445047], 
     [ 0.1877724 , 0.96060999, 0.39697999, 0.59078612], 
     [ 0.3239913 , 0.7786444 , 0.41692853, 0.10467392], 
     [ 0.58294263, 0.32025559, 0.6925856 , 1.7  ], 
     [ 0.7732126 , 0.48649481, 0.29771819, 1.91622924]]) 

आप उत्पादन नहीं बल्कि नहीं चाहते हैं:

क्योंकि यह अधिकतम हम देख रहे है, हम बस हर समूह में अंतिम प्रविष्टि है, जो एक बिल्कुल स्पष्ट बात करने के लिए लेने की जरूरत सॉर्ट किया गया है, लेकिन उन्हें मूल आदेश वे मूल सरणी में आया में रखने के लिए, आप भी perm की सहायता से प्राप्त कर सकते हैं कि:

>>> a_unique_max[np.argsort(perm[last])] 
array([[ 0.7732126 , 0.48649481, 0.29771819, 1.91622924], 
     [ 0.58294263, 0.32025559, 0.6925856 , 1.7  ], 
     [ 0.3239913 , 0.7786444 , 0.41692853, 0.10467392], 
     [ 0.12080023, 0.74853649, 0.15356663, 0.4505753 ], 
     [ 0.13536096, 0.60319054, 0.82018125, 0.10445047], 
     [ 0.1877724 , 0.96060999, 0.39697999, 0.59078612]]) 

यह केवल अधिकतम के लिए काम करेंगे, और यह एक द्वारा एक के रूप में आता सॉर्टिंग का उत्पाद। आप एक अलग समारोह के बाद कर रहे हैं, कहते हैं कि सभी एक ही-निर्देशांक प्रविष्टियों में से उत्पाद, आप की तरह कुछ कर सकता है:

>>> first = np.concatenate(([True], 
          np.all(a_sorted[:-1, :3] != a_sorted[1:, :3], axis=1))) 
>>> a_unique_prods = np.multiply.reduceat(a_sorted, np.nonzero(first)[0]) 

और आप अपनी वापसी सरणी इकट्ठा करने के लिए इन परिणामों के साथ चारों ओर एक छोटे से खेलने के लिए होगा।

-1

आप लॉजिकल इंडेक्सिंग का उपयोग कर सकते हैं।

मैं एक उदाहरण के लिए यादृच्छिक डेटा का उपयोग करेगा:

>>> myarr = np.random.random((6, 4)) 
>>> print(myarr) 
[[ 0.7732126 0.48649481 0.29771819 0.91622924] 
[ 0.58294263 0.32025559 0.6925856 0.0524125 ] 
[ 0.3239913 0.7786444 0.41692853 0.10467392] 
[ 0.12080023 0.74853649 0.15356663 0.4505753 ] 
[ 0.13536096 0.60319054 0.82018125 0.10445047] 
[ 0.1877724 0.96060999 0.39697999 0.59078612]] 

पंक्ति या पंक्तियों जहां अंतिम स्तंभ सबसे बड़ी है पाने के लिए, ऐसा करते हैं:

>>> greatest = myarr[myarr[:, 3]==myarr[:, 3].max()] 
>>> print(greatest) 
[[ 0.7732126 0.48649481 0.29771819 0.91622924]] 

क्या करता है यह हो जाता है myarr का अंतिम कॉलम, और उस कॉलम का अधिकतम पाता है, उस कॉलम के सभी तत्वों को अधिकतम के बराबर पाता है, और उसके बाद संबंधित पंक्तियां मिलती हैं।

+0

यह वह व्यवहार नहीं है जिसे मैं चाहता हूं। मैंने आशा व्यक्त करने के लिए इस सवाल को संपादित किया है कि यह और अधिक स्पष्ट हो। – Luca

-1

आप उपयोग कर सकते हैं np.argmax

x[np.argmax(x[:,3]),:]

>>> x = np.random.random((5,4)) 
>>> x 
array([[ 0.25461146, 0.35671081, 0.54856798, 0.2027313 ], 
     [ 0.17079029, 0.66970362, 0.06533572, 0.31704254], 
     [ 0.4577928 , 0.69022073, 0.57128696, 0.93995176], 
     [ 0.29708841, 0.96324181, 0.78859008, 0.25433235], 
     [ 0.58739451, 0.17961551, 0.67993786, 0.73725493]]) 
>>> x[np.argmax(x[:,3]),:] 
array([ 0.4577928 , 0.69022073, 0.57128696, 0.93995176]) 
+0

यह वह व्यवहार नहीं है जिसे मैं चाहता हूं। मैंने आशा व्यक्त करने के लिए इस सवाल को संपादित किया है कि यह और अधिक स्पष्ट हो। – Luca

2

मुझे लगता है कि आप टिप्पणियों में पांडा की तरफ पॉइंटर प्राप्त कर चुके हैं। एफडब्ल्यूआईडब्लू, यहां वांछित व्यवहार प्राप्त हो सकता है, यह मानते हुए कि आपको अंतिम क्रम क्रम की परवाह नहीं है क्योंकि समूहबी इसे बदलता है।

In [14]: arr 
Out[14]: 
array([[ 0.7732126 , 0.48649481, 0.29771819, 0.91622924], 
     [ 0.7732126 , 0.48649481, 0.29771819, 1.91622924], 
     [ 0.58294263, 0.32025559, 0.6925856 , 0.0524125 ], 
     [ 0.58294263, 0.32025559, 0.6925856 , 0.05  ], 
     [ 0.58294263, 0.32025559, 0.6925856 , 1.7  ], 
     [ 0.3239913 , 0.7786444 , 0.41692853, 0.10467392], 
     [ 0.12080023, 0.74853649, 0.15356663, 0.4505753 ], 
     [ 0.13536096, 0.60319054, 0.82018125, 0.10445047], 
     [ 0.1877724 , 0.96060999, 0.39697999, 0.59078612]]) 

In [15]: import pandas as pd 

In [16]: pd.DataFrame(arr) 
Out[16]: 
      0   1   2   3 
0 0.773213 0.486495 0.297718 0.916229 
1 0.773213 0.486495 0.297718 1.916229 
2 0.582943 0.320256 0.692586 0.052413 
3 0.582943 0.320256 0.692586 0.050000 
4 0.582943 0.320256 0.692586 1.700000 
5 0.323991 0.778644 0.416929 0.104674 
6 0.120800 0.748536 0.153567 0.450575 
7 0.135361 0.603191 0.820181 0.104450 
8 0.187772 0.960610 0.396980 0.590786 

In [17]: pd.DataFrame(arr).groupby([0,1,2]).max().reset_index() 
Out[17]: 
      0   1   2   3 
0 0.120800 0.748536 0.153567 0.450575 
1 0.135361 0.603191 0.820181 0.104450 
2 0.187772 0.960610 0.396980 0.590786 
3 0.323991 0.778644 0.416929 0.104674 
4 0.582943 0.320256 0.692586 1.700000 
5 0.773213 0.486495 0.297718 1.916229 
+0

धन्यवाद। बहुत अच्छा समाधान भी। मैं इसे विस्तार से भी तलाशने जा रहा हूं। – Luca

2

आप लगातार समान पहले तीन तत्वों के साथ प्रविष्टियों लाने के लिए lex-sorting इनपुट सरणी के साथ शुरू कर सकते हैं। फिर, अंतिम कॉलम प्रविष्टियों को संग्रहीत करने के लिए एक और 2 डी सरणी बनाएं, जैसे कि प्रत्येक डुप्लिकेट ट्रिपलेट के अनुरूप तत्व समान पंक्तियों में जाते हैं। इसके बाद, इस 2 डी सरणी के लिए के साथ max खोजें और इस प्रकार प्रत्येक अद्वितीय ट्रिपल के लिए अंतिम max आउटपुट है। यहाँ कार्यान्वयन है, इनपुट सरणी के रूप में A संभालने -

# Lex sort A 
sortedA = A[np.lexsort(A[:,:-1].T)] 

# Mask of start of unique first three columns from A 
start_unqA = np.append(True,~np.all(np.diff(sortedA[:,:-1],axis=0)==0,axis=1)) 

# Counts of unique first three columns from A 
counts = np.bincount(start_unqA.cumsum()-1) 
mask = np.arange(counts.max()) < counts[:,None] 

# Group A's last column into rows based on uniqueness from first three columns 
grpA = np.empty(mask.shape) 
grpA.fill(np.nan) 
grpA[mask] = sortedA[:,-1] 

# Concatenate unique first three columns from A and 
# corresponding max values for each such unique triplet 
out = np.column_stack((sortedA[start_unqA,:-1],np.nanmax(grpA,axis=1))) 

नमूना रन -

In [75]: A 
Out[75]: 
array([[ 1, 1, 1, 96], 
     [ 1, 2, 2, 48], 
     [ 2, 1, 2, 33], 
     [ 1, 1, 1, 24], 
     [ 1, 1, 1, 94], 
     [ 2, 2, 2, 5], 
     [ 2, 1, 1, 17], 
     [ 2, 2, 2, 62]]) 

In [76]: sortedA 
Out[76]: 
array([[ 1, 1, 1, 96], 
     [ 1, 1, 1, 24], 
     [ 1, 1, 1, 94], 
     [ 2, 1, 1, 17], 
     [ 2, 1, 2, 33], 
     [ 1, 2, 2, 48], 
     [ 2, 2, 2, 5], 
     [ 2, 2, 2, 62]]) 

In [77]: out 
Out[77]: 
array([[ 1., 1., 1., 96.], 
     [ 2., 1., 1., 17.], 
     [ 2., 1., 2., 33.], 
     [ 1., 2., 2., 48.], 
     [ 2., 2., 2., 62.]]) 
संबंधित मुद्दे