एनडी से 1 डी सरणियों तक


141

कहो मेरे पास एक सरणी है a:

a = np.array([[1,2,3], [4,5,6]])

array([[1, 2, 3],
       [4, 5, 6]])

मैं इसे 1 डी सरणी (यानी एक कॉलम वेक्टर) में बदलना चाहूंगा:

b = np.reshape(a, (1,np.product(a.shape)))

लेकिन यह रिटर्न

array([[1, 2, 3, 4, 5, 6]])

जो समान नहीं है:

array([1, 2, 3, 4, 5, 6])

मैं इस सरणी का पहला तत्व मैन्युअल रूप से इसे 1D सरणी में बदलने के लिए ले सकता हूं:

b = np.reshape(a, (1,np.product(a.shape)))[0]

लेकिन इसके लिए मुझे यह जानना होगा कि मूल आयाम में कितने आयाम हैं (और उच्च आयामों के साथ काम करते समय [0]

क्या एक मनमाना ndarray से एक कॉलम / पंक्ति वेक्टर प्राप्त करने का एक आयाम-स्वतंत्र तरीका है?

जवाबों:


277

Np.ravel (1D दृश्य के लिए) या का उपयोग करें np.ndarray.flatten (क -1 डी प्रति के लिए) या np.ndarray.flat (एक -1 डी इटरेटर के लिए):

In [12]: a = np.array([[1,2,3], [4,5,6]])

In [13]: b = a.ravel()

In [14]: b
Out[14]: array([1, 2, 3, 4, 5, 6])

ध्यान दें कि ravel()एक रिटर्न viewकी aजब संभव। इसलिए संशोधन bभी संशोधित करता हैa । जब 1 डी तत्व स्मृति में सन्निहित हैं, तो ravel()रिटर्न देता है view, लेकिन copyयदि कोई उदाहरण के लिए, aएक गैर-इकाई चरण आकार (उदाहरण a = x[::2]) का उपयोग करके किसी अन्य सरणी को टुकड़ा करने से बनाया जाता है ।

यदि आप एक दृश्य के बजाय एक प्रति चाहते हैं, तो उपयोग करें

In [15]: c = a.flatten()

यदि आप सिर्फ एक सूचना चाहते हैं, का उपयोग करें np.ndarray.flat:

In [20]: d = a.flat

In [21]: d
Out[21]: <numpy.flatiter object at 0x8ec2068>

In [22]: list(d)
Out[22]: [1, 2, 3, 4, 5, 6]

4
<पांडित्य> इस उदाहरण में, ravel()एक दृश्य देता है, लेकिन यह हमेशा सच नहीं होता है। ऐसे मामले हैं जहां ravel()एक प्रति लौटती है। </ pedantic>
Warren Weckesser

3
a.ravel()के रूप में उपवास के रूप में लगभग तीन गुना लग रहा है a.reshape(-1)a.flatten()रास्ता धीमा है, क्योंकि इसे एक प्रतिलिपि बनाने की आवश्यकता है।
बॉलपॉइंटबैन

25
In [14]: b = np.reshape(a, (np.product(a.shape),))

In [15]: b
Out[15]: array([1, 2, 3, 4, 5, 6])

या केवल:

In [16]: a.flatten()
Out[16]: array([1, 2, 3, 4, 5, 6])

11
b = a.reshape(-1)पहले उदाहरण में संक्षेप में उपयोग कर सकते हैं ।
सिरिटिस मेजर

5

flatten()इस उदाहरण की तरह उपयोग करने का सबसे सरल तरीका है :

 import numpy as np

 batch_y =train_output.iloc[sample, :]
 batch_y = np.array(batch_y).flatten()

मेरी सरणी यह ​​इस तरह थी:

    0
0   6
1   6
2   5
3   4
4   3
.
.
.

उपयोग करने के बाद flatten():

array([6, 6, 5, ..., 5, 3, 6])

यह इस प्रकार की त्रुटियों का हल भी है:

Cannot feed value of shape (100, 1) for Tensor 'input/Y:0', which has shape '(?,)' 

4

विभिन्न आकार के उपयोग के साथ सरणी की सूची के लिए निम्नलिखित हैं:

import numpy as np

# ND array list with different size
a = [[1],[2,3,4,5],[6,7,8]]

# stack them
b = np.hstack(a)

print(b)

आउटपुट:

[1 2 3 4 5 6 7 8]


तुम कैसे aवापस से आकार मिलेगा b?
DVDblk

यदि आप 1D को विखंडू में विभाजित करना चाहते हैं। इस देखें stackoverflow.com/a/8495740/6117565
बिक्रम

4

मैं जवाबों में उल्लिखित कार्यों के एक बेंचमार्क परिणाम को देखना चाहता था जिसमें अनटुबों भी शामिल है

यह भी इंगित करना चाहते हैं कि मामले में दृश्य के लिए उपयोग करने के लिए सुन्नत डॉक्टरarr.reshape(-1) बेहतर है। (हालांकि ravelनिम्नलिखित परिणाम में तेजी से tad है)


TL; DR : np.ravelसबसे अधिक प्रदर्शन करने वाला (बहुत कम राशि से) है।

बेंचमार्क

कार्य:

सुन्न संस्करण: '1.18.0'

विभिन्न ndarrayआकारों पर निष्पादन समय

+-------------+----------+-----------+-----------+-------------+
|  function   |   10x10  |  100x100  | 1000x1000 | 10000x10000 |
+-------------+----------+-----------+-----------+-------------+
| ravel       | 0.002073 |  0.002123 |  0.002153 |    0.002077 |
| reshape(-1) | 0.002612 |  0.002635 |  0.002674 |    0.002701 |
| flatten     | 0.000810 |  0.007467 |  0.587538 |  107.321913 |
| flat        | 0.000337 |  0.000255 |  0.000227 |    0.000216 |
+-------------+----------+-----------+-----------+-------------+

निष्कर्ष

ravelऔर reshape(-1)निष्पादन समय ndarray आकार से सुसंगत और स्वतंत्र था। हालाँकि, ravelतेज गति से, लेकिन reshapeआकार बदलने में लचीलापन प्रदान करता है। (शायद इसीलिए numpy doc इसके बजाय इसका इस्तेमाल करने की सलाह देते हैं। या कुछ मामले ऐसे भी हो सकते हैं जहाँ reshapeरिटर्न देखने और ravelन देने की)।
यदि आप बड़े आकार के ndarray के साथ काम कर रहे हैं, तो flattenप्रदर्शन समस्या का कारण बन सकता है। इसका उपयोग न करने की सलाह देते हैं। जब तक आपको कुछ और करने के लिए डेटा की प्रतिलिपि की आवश्यकता न हो।

प्रयुक्त कोड

import timeit
setup = '''
import numpy as np
nd = np.random.randint(10, size=(10, 10))
'''

timeit.timeit('nd = np.reshape(nd, -1)', setup=setup, number=1000)
timeit.timeit('nd = np.ravel(nd)', setup=setup, number=1000)
timeit.timeit('nd = nd.flatten()', setup=setup, number=1000)
timeit.timeit('nd.flat', setup=setup, number=1000)

0

यद्यपि यह np सरणी प्रारूप का उपयोग नहीं कर रहा है, (मेरे कोड को संशोधित करने के लिए आलसी के लिए) यह वही करना चाहिए जो आप चाहते हैं ... यदि, आप वास्तव में एक स्तंभ वेक्टर चाहते हैं तो आप वेक्टर परिणाम को स्थानांतरित करना चाहेंगे। यह सब इस बात पर निर्भर करता है कि आप इसे कैसे उपयोग करने की योजना बना रहे हैं।

def getVector(data_array,col):
    vector = []
    imax = len(data_array)
    for i in range(imax):
        vector.append(data_array[i][col])
    return ( vector )
a = ([1,2,3], [4,5,6])
b = getVector(a,1)
print(b)

Out>[2,5]

इसलिए अगर आपको ट्रांसपोज़ करने की ज़रूरत है, तो आप कुछ इस तरह से कर सकते हैं:

def transposeArray(data_array):
    # need to test if this is a 1D array 
    # can't do a len(data_array[0]) if it's 1D
    two_d = True
    if isinstance(data_array[0], list):
        dimx = len(data_array[0])
    else:
        dimx = 1
        two_d = False
    dimy = len(data_array)
    # init output transposed array
    data_array_t = [[0 for row in range(dimx)] for col in range(dimy)]
    # fill output transposed array
    for i in range(dimx):
        for j in range(dimy):
            if two_d:
                data_array_t[j][i] = data_array[i][j]
            else:
                data_array_t[j][i] = data_array[j]
    return data_array_t
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.