ND'den 1D'ye diziler


141

Diyelim ben bir dizi var a:

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

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

1D dizisine (yani bir sütun vektörü) dönüştürmek istiyorum:

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

ama bu geri dönüyor

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

ki aynı değil:

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

Manuel olarak 1D dizisine dönüştürmek için bu dizinin ilk öğesini alabilir:

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

ancak bu, orijinal dizinin kaç boyuta sahip olduğunu bilmemi gerektirir (ve daha yüksek boyutlarla çalışırken [0] 'ları bitiştir)

Rasgele bir ndarray'den sütun / satır vektörü almanın boyutlardan bağımsız bir yolu var mı?

Yanıtlar:


277

Kullanım np.ravel (1B görünümü için) ya da np.ndarray.flatten (1B kopya) ya da np.ndarray.flat (bir 1 D yineleyici için):

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

Mümkün olduğunda ravel()a viewdeğerini döndüren öğeyi unutmayın a. Böylece değişiklik bde değişir a. 1D öğeleri bellekte bitişik olduğunda ravel()bir a döndürür view, ancak copyörneğin abirim olmayan bir adım boyutu (örn. a = x[::2]) kullanılarak başka bir dizinin dilimlenmesinden bir if döndürür .

Görünüm yerine bir kopya istiyorsanız,

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

Sadece bir yineleyici istiyorsanız, şunu kullanın 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
<pedantic> Bu örnekte ravel()bir görünüm döndürür, ancak bu her zaman doğru değildir. ravel()Bir kopyasını döndüren durumlar vardır . </
pedantic

3
a.ravel()3 kat daha hızlı görünüyor a.reshape(-1). a.flatten()bir kopyasını yapması gerektiğinden çok daha yavaştır.
BallpointBen

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

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

ya da sadece:

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

11
b = a.reshape(-1)İlk örnekte kısaca kullanılabilir .
Syrtis Major

5

En basit yollardan biri flatten(), bu örnek gibi kullanmaktır :

 import numpy as np

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

Dizim şöyle oldu:

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

Kullandıktan sonra flatten():

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

Ayrıca bu tür hataların çözümü:

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

4

Farklı boyuta sahip dizi listesi için aşağıdakileri kullanın:

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)

Çıktı:

[1 2 3 4 5 6 7 8]


asırt şeklini nasıl alırsın b?
dvdblk

1D'yi parçalara bölmek istiyorsanız. Bu stackoverflow.com/a/8495740/6117565
bikram

4

Unutulanlar da dahil olmak üzere cevaplarda bahsedilen fonksiyonların karşılaştırmalı değerlendirmesini görmek istedim .

Ayrıca numpy doc'ınarr.reshape(-1) görünümün tercih edilebilir olması durumunda kullanılmasını önerdiğini belirtmek isteriz . ( ravelaşağıdaki sonuçta biraz daha hızlı olmasına rağmen )


TL; DR : np.ravelen yüksek performanstır (çok az miktarda).

Karşılaştırma

Fonksiyonlar:

numpy sürümü: '1.18.0'

Farklı ndarrayboyutlarda uygulama süreleri

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

Sonuç

ravelve reshape(-1)yürütme süresi tutarlı ve ndarray boyutundan bağımsızdı. Bununla birlikte, ravelbiraz daha hızlıdır, ancak reshapeboyutu yeniden şekillendirmede esneklik sağlar. (belki de bu yüzden numpy doc bunu kullanmanızı önerir. Ya da reshapegeri dönüşlerin görüntülenip görünmediği bazı durumlar olabilir ravel).
Büyük boyutlu ndarray ile uğraşıyorsanız, kullanmak flattenbir performans sorununa neden olabilir. Kullanmamanızı tavsiye ederiz. Başka bir şey yapmak için verilerin bir kopyasına ihtiyacınız olmadığı sürece.

Kullanılan kod

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

Bu np dizi biçimini kullanmasa da, (kodumu değiştirmek için tembel olmak için) bu istediğinizi yapmalıdır ... Eğer gerçekten bir sütun vektörü istiyorsanız, vektör sonucunu aktarmak istersiniz. Her şey bunu nasıl kullanmayı planladığınıza bağlıdır.

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]

Bu yüzden transpoze etmeniz gerekiyorsa, böyle bir şey yapabilirsiniz:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.