2012-09-30 11 views
10

मैं समझने की कोशिश कर रहा हूं कि कमी करने के लिए एनडिटर के साथ कैसे काम करना है, मेरे मामले में एक 3 डी सरणी को 2 डी सरणी में परिवर्तित करना।पहली धुरी में numpy.nditer के साथ कमी कैसे करें

मैं यहाँ मदद पीछा http://docs.scipy.org/doc/numpy/reference/arrays.nditer.html और इनपुट के अंतिम अक्ष से अधिक कमी लागू होने वाला एक समारोह बनाने में कामयाब रहे। इस समारोह के साथ

def nditer_sum(data, red_axes): 
    it = numpy.nditer([data, None], 
      flags=['reduce_ok', 'external_loop'], 
      op_flags=[['readonly'], ['readwrite', 'allocate']], 
      op_axes=[None, red_axes]) 
    it.operands[1][...] = 0 

    for x, y in it: 
     y[...] = x.sum() 

    return it.operands[1] 

मैं कुछ data.sum के बराबर प्राप्त कर सकते हैं (अक्ष = 2)

>>> data = numpy.arange(2*3*4).reshape((2,3,4)) 
>>> nditer_sum(data, [0, 1, -1]) 
[[ 6 22 38] 
[54 70 86]] 
>>> data.sum(axis=2) 
[[ 6 22 38] 
[54 70 86]] 

तो कुछ data.sum के बराबर लाने के लिए (अक्ष = 0) मैं हालांकि यह है कि तर्क red_axes को [-1, 0,1] पर बदलने के लिए पर्याप्त था लेकिन परिणाम काफी अलग है।

>>> data = numpy.arange(2*3*4).reshape((2,3,4)) 
>>> data.sum(axis=0) 
[[12 14 16 18] 
[20 22 24 26] 
[28 30 32 34]] 
>>> nditer_sum(data, [-1, 0, 1]) 
[[210 210 210 210] 
[210 210 210 210] 
[210 210 210 210]] 

में यह में nditer_sum अंदर पाश (एक्स के लिए, वाई के लिए :), इटरेटर 2 बार पाशन और 12 बार पाशन की लंबाई 12 हर बार की एक सरणी देने के बजाय और एक सरणी दे रहा है प्रत्येक बार लंबाई 2। मेरे पास कई बार डिस्प्ले दस्तावेज़ों को पढ़ता है और इसके बारे में पर कोई फायदा नहीं हुआ है। मैं numpy 1.6 और अजगर 2.7

+0

-1 op_axes में "नई धुरी 'के रूप में दर्ज है, यह आप क्या कोशिश कर रहे हैं करने के लिए? इसके अलावा प्रलेखन [[आकार x], [आकार y], [आकार z]] को op_axes में फ़ीड करता है, जबकि आप [कोई नहीं, [आकार 3]] दबाते हैं, क्या इसका इरादा है? –

+0

[प्रलेखन] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.nditer.html) कहता है "एक ऑपरेंड ऑपरेटर के आयामों से ऑपरेटर के आयामों से मैपिंग है" ... उसका मतलब जो भी हो। वर्तमान उदाहरण में मैंने [iterating over arrays tutorial] में कोड कॉपी किया है (http://docs.scipy.org/doc/numpy-dev/reference/arrays.nditer.html#reduction-iteration), जो काम करता है, लेकिन केवल अंतिम धुरी के साथ। उदाहरण में, 3 डी सरणी में op_axes कोई नहीं है (जो [-1, -1, -1] के बराबर लगता है) और 2 डी अक्ष में [0, 1, -1] – Sergio

+0

है, हालांकि मैं बदल रहा हूं [0,1, - 1] से [-1, 0, 1] पहली धुरी में कमी करेगा, लेकिन यह काम नहीं करता है।मेरा सवाल यह है कि मनमानी धुरी पर कमी कैसे करें। – Sergio

उत्तर

0

उपयोग कर रहा हूँ लाइन बदलने (उदाहरण के here के रूप में) y[...] = x.sum()y[...] += x करने के लिए इसे ठीक करता है।

+0

लेकिन यह वह नहीं है जो मैं करना चाहता हूं। मैं एक और जटिल कार्य का उपयोग कर रहा हूं जो एक्स पर संचालन का एक गुच्छा करता है। कल्पना कीजिए कि योग की बजाय "10% निचले और एक्स के उच्चतम क्लिपिंग के बाद योग" – Sergio

+0

मैं बस इतना कह रहा हूं कि फिक्स numpy.sum के साथ व्यवहार को किसी भी अक्ष निर्दिष्ट के साथ संगत बनाता है, जो सवाल प्रतीत होता है। .. शायद आपको प्रश्न में विवरण जोड़ना चाहिए। – Benjamin

1

axis=0 केस nditer क्रम में F में बदल दिया गया है, तो सही तरीके से काम करता है। अब आप चाहते थे आकार के सरणी (2,) के साथ 12 कदम हैं।

it = np.nditer([data, None], 
     flags=['reduce_ok', 'external_loop'], 
     op_flags=[['readonly'], ['readwrite', 'allocate']], 
     order='F',  # ADDED to loop starting with the last dimension 
     op_axes=[None, red_axes]) 

लेकिन मध्य axis=1 मामले के लिए ऐसा कोई समाधान नहीं है।


एक और दृष्टिकोण चयनित आयामों पर पुनरावृत्ति करने के लिए एक कम आयामी सरणी पर एक 'multi_index' इटरेटर के निर्माण के लिए है। मैंने https://stackoverflow.com/a/25097271/901925 में खोज की है कि np.ndindex इस चाल का उपयोग 'उथला पुनरावृत्ति' करने के लिए करता है।

axis=0 मामले के लिए, इस समारोह काम करता है:

def sum_1st(data): 
    y = np.zeros(data.shape[1:], data.dtype) 
    it = np.nditer(y, flags=['multi_index']) 
    while not it.finished: 
     xindex = tuple([slice(None)]+list(it.multi_index)) 
     y[it.multi_index] = data[xindex].sum() 
     it.iternext() 
    return y 

या किसी अक्ष का सामान्यीकरण:

def sum_any(data, axis=0): 
    yshape = list(data.shape) 
    del yshape[axis] 
    y = np.zeros(yshape, data.dtype) 
    it = np.nditer(y, flags=['multi_index']) 
    while not it.finished: 
     xindex = list(it.multi_index) 
     xindex.insert(axis, slice(None)) 
     y[it.multi_index] = data[xindex].sum() 
     it.iternext() 
    return y 
संबंधित मुद्दे