Arrays als Listenelemente

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
HoWei
User
Beiträge: 12
Registriert: Freitag 28. Juni 2019, 10:18

Ich möchte eine 2D-Liste (2x3) in der jedes Listenelement eine 4x8 Matrix, bzw. ein numpy-Array ist.
Zuerst erstelle ich die 2x3 Liste und dann weise ich jedem Listenelement ein 4x8 Array zu.
Zur Verifikation nummeriere ich jeden Zeilenvektor vom Array mit einem laufenden Zähler.

Insgesamt sind das 2x3x4=24 Array-Achsen, bzw. Vektoren.

Das funktioniert so wie unten angeschrieben, aber sind doch recht viele for-Schleifen.

Gibt es eine bessere/effizientere/übersichtlichere Möglichkeit dies zu tun ?
Vor allem die Zusweisung der Arrays an jedes einzelne Listenelement kann doch bestimmt auch in einem Einzeiler formuliert werden, oder ?

Code: Alles auswählen

import numpy as np

#create a 2x3 list: 5 columns, 3 rows
list_row = 2
list_col = 3
mylist = [ [0 for j in range(list_col)] for i in range (list_row) ] 

#numpy array dimensions
arry_row = 4
arry_col = 8

#assign an 2x8 numpy array to each element of the list
for i in range(list_row):		#row index			
	for j in range(list_col):	#columns index		
		mylist[i][j] = np.zeros((arry_row,arry_col)) #create a 2x8 numpy array filled with 0s

#then fill each numpy array-element with its row index
for i in range(list_row):		#row list-index

	for j in range(list_col):	#column list-index	
	
		for k in range(arry_row): 	#each column
			array_column = int( k + j*arry_row + i*list_col*arry_row ) #running column of array element
			
			for l in range(arry_col):	#assign to each of the array elements its corresponsing array-row-index
				(mylist[i][j])[k][l] = array_column
					
				
print(mylist)  
Ergebnis:

Code: Alles auswählen

[[array([[0., 0., 0., 0., 0., 0., 0., 0.],
       [1., 1., 1., 1., 1., 1., 1., 1.],
       [2., 2., 2., 2., 2., 2., 2., 2.],
       [3., 3., 3., 3., 3., 3., 3., 3.]]), array([[4., 4., 4., 4., 4., 4., 4., 4.],
       [5., 5., 5., 5., 5., 5., 5., 5.],
       [6., 6., 6., 6., 6., 6., 6., 6.],
       [7., 7., 7., 7., 7., 7., 7., 7.]]), array([[ 8.,  8.,  8.,  8.,  8.,  8.,  8.,  8.],
       [ 9.,  9.,  9.,  9.,  9.,  9.,  9.,  9.],
       [10., 10., 10., 10., 10., 10., 10., 10.],
       [11., 11., 11., 11., 11., 11., 11., 11.]])], [array([[12., 12., 12., 12., 12., 12., 12., 12.],
       [13., 13., 13., 13., 13., 13., 13., 13.],
       [14., 14., 14., 14., 14., 14., 14., 14.],
       [15., 15., 15., 15., 15., 15., 15., 15.]]), array([[16., 16., 16., 16., 16., 16., 16., 16.],
       [17., 17., 17., 17., 17., 17., 17., 17.],
       [18., 18., 18., 18., 18., 18., 18., 18.],
       [19., 19., 19., 19., 19., 19., 19., 19.]]), array([[20., 20., 20., 20., 20., 20., 20., 20.],
       [21., 21., 21., 21., 21., 21., 21., 21.],
       [22., 22., 22., 22., 22., 22., 22., 22.],
       [23., 23., 23., 23., 23., 23., 23., 23.]])]]
       
Benutzeravatar
__blackjack__
User
Beiträge: 13107
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@HoWei: Als erstes solltest Du mindestens bei den Listen aufhören da irgendwelche Dummylisten mit Dummywerten zu erzeugen die dann später durch die tatsächlichen Werte ersetzt werden. Listen werden in Python in aller Regel dynamisch erzeugt, das heisst man fängt mit einer leeren Liste an und hängt da dann die Werte an, die sie enthalten soll. Alternativ kann man so eine Schleife ab und zu auch recht kompakt als „list comprehension“ ausdrücken.

Bei den Arrays ist es ziemlich umständlich und im Grunde falsch die Werte darin in einer doppelten Schleife einzeln alle durch dneue Werte zu ersetzen. Wenn man für Numpy-Arrays Schleifen verwendet, macht man in der Regel etwas falsch.

Edit:

Code: Alles auswählen

#!/usr/bin/env python3
from itertools import count

import numpy as np
from more_itertools import take


def main():
    list_row_count = 2
    list_column_count = 3
    array_row_count = 4
    array_column_count = 8
    
    row_numbers = count()
    result = list()
    for _ in range(list_row_count):
        row = list()
        for _ in range(list_column_count):
            row.append(
                np.array(take(array_row_count, row_numbers), dtype=float)
                    .reshape((-1, 1))
                    .repeat(array_column_count, axis=1)
            )
        result.append(row)
    
    print(result)


if __name__ == '__main__':
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
HoWei
User
Beiträge: 12
Registriert: Freitag 28. Juni 2019, 10:18

Genau, da stimme ich 100% zu - deshalb habe ich dieses Beispiel hier gepostet, denn ich möchte lernen wie man das besser machen kann.

Die Rahmenbedingungen sind:
- ich habe pro Pixel die Pixelmesswerte in der Form einer 4x8 Matrix
- und ich habe 2x3 Pixel

Das Pixelfeld soll so aussehen:

Code: Alles auswählen

[ [Pix0,0 Pix0,1 Pix0,2]
  [Pix1,0 Pix1,1 Pix1,2]
  [Pix2,0 Pix2,1 Pix1,2] ]

mit den Pixelmesswerten PMW pro Pixel

Code: Alles auswählen

Pix0,0 = 
[ [PMW0,0  PMW0,1 ... PMW0,7 ]
  [PMW1,0 ...        PMW1,7 ]
  [...                      ]
  [PMW3,0  ...      PMW3,7 ] ]

Am Besten wäre es nur numpy-Arrays zu verwenden, aber geht das und wie würden Profis das machen ?

[EDIT:] Habe grade erst realisiiert, dass da ein Code-Beispiel in der Antwort war - guck ich mir an.
HoWei
User
Beiträge: 12
Registriert: Freitag 28. Juni 2019, 10:18

Ich kann das angehängte Beispiel nicht ausführen, wegen:

from more_itertools import take
ModuleNotFoundError: No module named 'more_itertools'

Ich verwende Python36
Benutzeravatar
__blackjack__
User
Beiträge: 13107
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@HoWei: `more_itertools` ist nicht Bestandteil der Standardbibliothek, das muss man wie Numpy auch, zusätzlich installieren.

Klar kann man das auch in *einem* Array speichern, Du brauchst halt einfach nur die beiden Dimensionen mehr, die Du jetzt in den Listen stecken hast.

Code: Alles auswählen

    result = (
        np.arange(
            list_row_count * list_column_count * array_row_count, dtype=float
        )
            .reshape((-1, 1))
            .repeat(array_column_count, axis=1)
            .reshape(
                (
                    list_row_count,
                    list_column_count,
                    array_row_count,
                    array_column_count,
                )
            )
    )
    print(result)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
HoWei
User
Beiträge: 12
Registriert: Freitag 28. Juni 2019, 10:18

Das ist schön und ich glaub jetzt hab ich es kapiert - ich habe einen Einzeiler gefunden, der jedes Element durchlaufend nummeriert. Die Dimensionen der Matrix sind dieselben.

So wirds gemacht, oder ?

Code: Alles auswählen

>>>np.arange(2*3*4*8).reshape(2,3,4,8)
array([[[[  0,   1,   2,   3,   4,   5,   6,   7],
         [  8,   9,  10,  11,  12,  13,  14,  15],
         [ 16,  17,  18,  19,  20,  21,  22,  23],
         [ 24,  25,  26,  27,  28,  29,  30,  31]],

        [[ 32,  33,  34,  35,  36,  37,  38,  39],
         [ 40,  41,  42,  43,  44,  45,  46,  47],
         [ 48,  49,  50,  51,  52,  53,  54,  55],
         [ 56,  57,  58,  59,  60,  61,  62,  63]],

        [[ 64,  65,  66,  67,  68,  69,  70,  71],
         [ 72,  73,  74,  75,  76,  77,  78,  79],
         [ 80,  81,  82,  83,  84,  85,  86,  87],
         [ 88,  89,  90,  91,  92,  93,  94,  95]]],


       [[[ 96,  97,  98,  99, 100, 101, 102, 103],
         [104, 105, 106, 107, 108, 109, 110, 111],
         [112, 113, 114, 115, 116, 117, 118, 119],
         [120, 121, 122, 123, 124, 125, 126, 127]],

        [[128, 129, 130, 131, 132, 133, 134, 135],
         [136, 137, 138, 139, 140, 141, 142, 143],
         [144, 145, 146, 147, 148, 149, 150, 151],
         [152, 153, 154, 155, 156, 157, 158, 159]],

        [[160, 161, 162, 163, 164, 165, 166, 167],
         [168, 169, 170, 171, 172, 173, 174, 175],
         [176, 177, 178, 179, 180, 181, 182, 183],
         [184, 185, 186, 187, 188, 189, 190, 191]]]])

Antworten