मैं कई 2D C सन्निहित छवि सरणियों को एक 3D वॉल्यूम में लोड करना चाहता हूं और उन्हें सहज अनुक्रमण के माध्यम से एक्सेस करना चाहता हूं, उदा। slice3 = volume[:,:,2] जिसके लिए मूल संघटित 1D निरूपण से कुछ पुन: आकार देने की आवश्यकता है।

अब, चूंकि मैं बहुत सारी छवियों को लोड करता हूं और इससे और भी नए वॉल्यूम की गणना करता हूं, जो आपके औसत पीसी पर काम करना है, मैं स्मृति उपयोग के साथ-साथ गणना प्रदर्शन के बारे में चिंतित हूं।

प्र: मैं 3D वॉल्यूम के साथ-साथ 2D स्लाइस को एक साथ रखने के लिए कैसे प्राप्त कर सकता हूं, इसलिए मैं वॉल्यूम पर कुछ सामान और कुछ अलग-अलग स्लाइस पर कुशलतापूर्वक कर सकता हूं।

खेलने के लिए यहां कुछ उदाहरण दिया गया है:

import numpy as np

# dimensions:
rows   = 2
cols   = 2
slices = 3

# create array
a = np.arange(rows*cols*slices)
print(a)
# [ 0  1  2  3  4  5  6  7  8  9 10 11]
# this is the original concatenated input of the slices [[0,1],[2,3]], [[4,5],[6,7]], [[8,9],[10,11]]

# a contiguous?
print(a.flags['C_CONTIGUOUS'])
# True

a = a.reshape(rows,cols,slices)
print(a)
# a still contiguous?
print(a.flags['C_CONTIGUOUS'])
# True

# what about a slice?
print(a[:,:,0])
# [[0 3]
#  [6 9]]
# ouch! that's not the slice I wanted! I wanted to keep [[0,1],[2,3]] together
# this slice is of course also not contiguous:
print(a[:,:,0].flags['C_CONTIGUOUS'])
# False

# ok, let's start over
a = a.ravel()
print(a)
# [ 0  1  2  3  4  5  6  7  8  9 10 11]
a = a.reshape(slices,rows,cols)
a = a.swapaxes(0,1)
a = a.swapaxes(1,2)
# what about a slice?
print(a[:,:,0])
# [[0 1]
#  [2 3]]
# now that's the kind of slice I wanted!

# a still contiguous?
print(a.flags['C_CONTIGUOUS'])
# False

# slice contiguous?
print(a[:,:,0].flags['C_CONTIGUOUS'])
# True
# only halfway there.. :(

फिर से: क्या वॉल्यूम के साथ-साथ अलग-अलग स्लाइस C को सन्निहित रखते हुए वांछित स्लाइस इंडेक्सिंग प्राप्त करने का कोई तरीका है?

1
Greg814 24 सितंबर 2020, 22:16

2 जवाब

सबसे बढ़िया उत्तर

विकल्प 1

slices किस आयाम से मेल खाता है, इस पर बहुत देर न करें:

a = a.reshape(slices, rows, cols)

उसे पूरी तरह छोड़ दो। एक अच्छा साइड-इफ़ेक्ट यह है कि कहने के लिए स्लाइस 1, आप बस करते हैं

a[1]

a[1, :, :] या a[1, ...] की कोई आवश्यकता नहीं है।

विकल्प 2

यदि आप स्लाइस से मेल खाने वाले आयाम पर अटक जाते हैं, तो आपको संगति बनाए रखने के लिए डेटा को कॉपी करना होगा। हालांकि, आप स्वैपेक्स दो बार।

एक तरीका है transpose का इस्तेमाल करना :

a = a.reshape(slices, rows, cols).transpose(1, 2, 0)

या आप np.moveaxis का इस्तेमाल कर सकते हैं:

a = np.moveaxis(a.reshape(slices, rows, cols), 0, -1)
2
Mad Physicist 24 सितंबर 2020, 22:46

नहीं, एक 3D सरणी a का C-सन्निहित होना और a[:,:,0] का C-संगत होना असंभव है।

क्यों? परिभाषा के अनुसार, सी-सन्निहित सरणी में अंतिम आयाम में एक इकाई स्ट्राइड होता है, उदाहरण के लिए

>>> a = np.arange(rows*cols*slices)
>>> a = a.reshape(slices,rows,cols)
>>> print([stride // a.itemsize for stride in a.strides])
[4, 2, 1]

किसी भी सी-सन्निहित सरणी के लिए, अंतिम आयाम को काटने से एक गैर-सी-सन्निहित सरणी बन जाएगी, क्योंकि इसमें अंतिम आयाम में एक इकाई स्ट्राइड नहीं हो सकता है:

>>> b = a[:, :, 0]
>>> print([stride // b.itemsize for stride in b.strides])
[4, 2]

यदि आप चाहते हैं कि आपके स्लाइस सी-सन्निहित हों, तो आपको पहले आयाम और केवल पहले आयाम में स्लाइस करने की आवश्यकता होगी:

>>> c = a[0, :, :]
>>> print([stride // c.itemsize for stride in c.strides])
[2, 1]
1
jakevdp 24 सितंबर 2020, 22:48