Dari susunan ND ke 1D


141

Katakanlah saya punya array a:

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

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

Saya ingin mengonversinya menjadi array 1D (yaitu vektor kolom):

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

tapi ini kembali

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

yang tidak sama dengan:

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

Saya bisa menggunakan elemen pertama array ini untuk mengubahnya secara manual menjadi array 1D:

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

tetapi ini mengharuskan saya untuk mengetahui berapa banyak dimensi yang dimiliki array asli (dan menyatukan [0] ketika bekerja dengan dimensi yang lebih tinggi)

Apakah ada cara dimensi-independen untuk mendapatkan vektor kolom / baris dari ndarray yang arbitrer?

Jawaban:


277

Gunakan np.ravel (untuk tampilan 1D) atau np.ndarray.flatten (untuk salinan 1D) atau np.ndarray.flat (untuk iterator 1D):

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

Perhatikan bahwa ravel()mengembalikan viewdari abila memungkinkan. Jadi memodifikasi bjuga memodifikasi a. ravel()mengembalikan a viewketika elemen 1D berdekatan dalam memori, tetapi akan mengembalikan copyjika, misalnya, adibuat dari mengiris array lain menggunakan ukuran langkah non-unit (misalnya a = x[::2]).

Jika Anda ingin salinan daripada tampilan, gunakan

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

Jika Anda hanya menginginkan iterator, gunakan 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> Dalam contoh ini, ravel()mengembalikan tampilan, tetapi itu tidak selalu benar. Ada kasus di mana ravel()mengembalikan salinan. </pedantic>
Warren Weckesser

3
a.ravel()terlihat sekitar tiga kali lebih cepat a.reshape(-1). a.flatten()lebih lambat, karena perlu membuat salinan.
BallpointBen

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

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

atau, cukup:

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

11
Dapat digunakan b = a.reshape(-1)untuk pendek dalam contoh pertama.
Syrtis Major

5

Salah satu cara paling sederhana adalah menggunakan flatten(), seperti contoh ini:

 import numpy as np

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

Array saya seperti ini:

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

Setelah menggunakan flatten():

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

Ini juga solusi kesalahan jenis ini:

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

4

Untuk daftar array dengan ukuran berbeda gunakan sebagai berikut:

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)

Keluaran:

[1 2 3 4 5 6 7 8]


Bagaimana Anda mendapatkan bentuk apunggung b?
dvdblk

Jika Anda ingin membagi 1D menjadi potongan-potongan. Lihat stackoverflow.com/a/8495740/6117565
bikram

4

Saya ingin melihat hasil tolok ukur fungsi yang disebutkan dalam jawaban termasuk unutbu .

Juga ingin menunjukkan bahwa numpy doc merekomendasikan untuk digunakan arr.reshape(-1)dalam tampilan kasus lebih disukai. (meskipun ravelsedikit lebih cepat dalam hasil berikut)


TL; DR : np.raveladalah yang paling performan (dengan jumlah yang sangat kecil).

Tolok ukur

Fungsi:

versi numpy: '1.18.0'

Waktu eksekusi pada ndarrayukuran yang berbeda

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

Kesimpulan

raveldan reshape(-1)waktu eksekusi konsisten dan independen dari ukuran ndarray. Namun, ravelini sedikit lebih cepat, tetapi reshapememberikan fleksibilitas dalam membentuk kembali ukuran. (mungkin itu sebabnya numpy doc merekomendasikan untuk menggunakannya sebagai gantinya. Atau mungkin ada beberapa kasus di mana reshapemengembalikan tampilan dan raveltidak).
Jika Anda berurusan dengan ndarray ukuran besar, menggunakan flattendapat menyebabkan masalah kinerja. Rekomendasikan untuk tidak menggunakannya. Kecuali jika Anda memerlukan salinan data untuk melakukan sesuatu yang lain.

Kode yang digunakan

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

Meskipun ini tidak menggunakan format array np, (untuk malas memodifikasi kode saya) ini harus melakukan apa yang Anda inginkan ... Jika, Anda benar-benar ingin vektor kolom Anda ingin mengubah hasil vektor. Itu semua tergantung pada bagaimana Anda berencana untuk menggunakan ini.

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]

Jadi, jika Anda perlu mengubah posisi, Anda dapat melakukan sesuatu seperti ini:

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.