Porównanie dwóch macierzy Python

0

Witam,
Jestem początkującym użytkownikiem pythona i muszę zmierzyć z dość skomplikowanym dla mnie problemem.
Muszę wykonać mnożenie macierzy, które wyjściowo mają różne rozmiary. Mam jedną macierz główną ktora zawiera wszystkie warianty i drugą która zawiera tylko niektóre z nich. Muszę tak uporządkować moje dane w obu macierzach aby poszczególne warianty w obu macierzach sobie odpowiadały czyli w mniejszej macierzy umieścić zera w odpowiednich miejscach.
Chcę napisać funkcję w której stworzę macierz o wymiarach macierzy głównej, ale wypełnioną zerami. Nastepnie porównć dane z mniejszej macierzy ( pierwsze trzy wartości w wierszu) z danymi z macierzy głównej i jeśli są one takie same to zapisać cały wiersz w danej linijce mniejszej macierzy. Jeśli danemu wierszowi macierzy głównej nie odpowiada żaden wiersz mniejszej macierzy wtedy zostawić wiersz wypełniony zerami.
Czy może ktoś mógłby mi podpowiedzieć od czego powinnam zacząć i jakie funkcje mogłyby być przydatne żebym mogła się z nimi zapoznać?

0

m:

A a 1 68 35 44

A a 2 77 91 48

A a 3 1 63 86

A a 4 52 31 25

A a 5 99 85 18

A a 6 47 74 19

A a 7 34 100 67

A a 8 44 68 92

A a 9 38 14 91

A a 10 15 67 18

B b 1 9 84 27

B b 3 16 87 68

B b 4 78 84 38

B b 5 75 46 61

B b 6 79 89 48

B b 8 35 26 69

B b 9 92 93 88

C c 1 14 85 24

C c 2 62 69 66

C c 4 52 8 81

C c 6 91 44 37

C c 7 64 96 0

C c 9 40 33 7

C c 10 75 41 63

G:

A a 1 34 564 366

A a 2 643 0 6

A a 3 3 45 0

A a 4 0 0 45

A a 5 456 7 68

A a 6 57 23 0

A a 7 66 76 879

A a 8 787 0 435

A a 9 2 98 0

A a 10 0 68 35

B b 1 12 43 789

B b 2 12 43 789

B b 3 57 57 97

B b 4 57 14 0

B b 5 36 897 2

B b 6 254 64 58

B b 7 254 64 58

B b 8 46 24 0

B b 9 46 79 32

B b 10 46 79 32

C c 1 35 6 7

C c 2 436 68 2

C c 3 436 68 2

C c 4 356 0 6

C c 5 356 0 6

C c 6 345 7 57

C c 7 57 79 9

C c 8 57 79 9

C c 9 54 46 8

C c 10 86 57 0
To są dwie macierze, które chce pomnożyć. Problem polega na tym , że dla każdego A a B b C powinien być wiersz z wartością 1-10 w trzeciej kolumnie. Gdy go brakuje chcę w odpowiednim miejscu dodać wiersz zer.
Ważne jest też to, że w kolumnach 4-6 wartości są różne w obu macierzach Ogólnie te dwie macierze stworzyłam tylko na potrzebę napisania programu. Oryginalnie moja macierz główna ma wymiar 21120x21120.

0

Czyli macierz m chcę zastąpić:
A a 1 68 35 44

A a 2 77 91 48

A a 3 1 63 86

A a 4 52 31 25

A a 5 99 85 18

A a 6 47 74 19

A a 7 34 100 67

A a 8 44 68 92

A a 9 38 14 91

A a 10 15 67 18

B b 1 9 84 27

0 0 0 0 0 0

B b 3 16 87 68

B b 4 78 84 38

B b 5 75 46 61

B b 6 79 89 48

0 0 0 0 0 0

B b 8 35 26 69

B b 9 92 93 88

0 0 0 0 0 0

C c 1 14 85 24

C c 2 62 69 66

0 0 0 0 0 0

C c 4 52 8 81

0 0 0 0 0 0

C c 6 91 44 37

C c 7 64 96 0

0 0 0 0 0 0

C c 9 40 33 7

C c 10 75 41 63

na razie zrobiłam coś takiego, ale wtedy program po prostu zatrzymuje się przy pierwszej różnicy
with open ('NotFull_data.txt', 'rb') as NotFull, open('Full_data.txt', 'rb') as Full:

for row1, row2 in zip(NotFull,Full):

    while row1 == row2:

        print(row1)

        if row1 != row2:
0

W sumie to takie macierze lepiej obrazują mój przypadek

A a 1 34 564 366

A a 2 643 0 6

A a 3 3 45 0

A b 1 0 0 45

A b 2 456 7 68

A b 3 57 23 0

A c 1 66 76 879

A c 2 787 0 435

A c 3 2 98 0

B a 1 12 43 789

B a 2 12 43 789

B a 3 57 57 97

B b 1 57 14 0

B b 2 36 897 2

B b 3 254 64 58

B c 1 254 64 58

B c 2 46 24 0

B c 3 46 79 32

C a 1 35 6 7

C a 2 436 68 2

C a 3 436 68 2

C b 1 356 0 6

C b 2 356 0 6

C b 3 345 7 57

C c 1 57 79 9

C c 2 57 79 9

C c 3 54 46 8

m:

A a 1 68 35 44

A a 2 77 91 48

A a 3 1 63 86

A b 1 52 31 25

A b 2 99 85 18

A b 3 47 74 19

A c 1 34 100 67

A c 2 44 68 92

A c 3 38 14 91

B a 1 9 84 27

B a 3 16 87 68

B b 1 78 84 38

B b 2 75 46 61

B b 3 79 89 48

B c 1 35 26 69

B c 2 92 93 88

C a 1 14 85 24

C a 2 62 69 66

C b 1 52 8 81

C b 3 91 44 37

C c 2 64 96 0

C c 3 40 33 7

Przeksztalcone m:

A a 1 68 35 44

A a 2 77 91 48

A a 3 1 63 86

A b 1 52 31 25

A b 2 99 85 18

A b 3 47 74 19

A c 1 34 100 67

A c 2 44 68 92

A c 3 38 14 91

B a 1 9 84 27

0 0 0 0 0 0

B a 3 16 87 68

B b 1 78 84 38

B b 2 75 46 61

B b 3 79 89 48

B c 1 35 26 69

B c 2 92 93 88

0 0 0 0 0 0

C a 1 14 85 24

C a 2 62 69 66

0 0 0 0 0 0

C b 1 52 8 81

0 0 0 0 0 0

C b 3 91 44 37

0 0 0 0 0 0

C c 2 64 96 0

C c 3 40 33 7
Pomysł miałam taki żeby macierz przekształcona była mp = np.zeroes((27,6)) w której uzupełnię wiersze wartościami z m gdy trzy pierwsze kolumny są takie same w G i m, a pozostałe wiersze pominę pozostawiając je zerami. Niestety brak mi po prostu umiejętności i doświadczenia żeby to zrobić.

1

Myślę, że łatwiej byłoby Ci pomóc gdybyś przejrzyście opisał swój problem. Np. :

Mam macierz A : http://absta.pl/wykad-13-wyznaczniki-minory-rzd-macierzy-macierz-odwrotna-13-1/10667_html_28dac88b.gif i macierz B: <tu link też>. Dokonuję operacji X by otrzymać macierz C: <link>. Same przepisane liczby nie mówią nic na pierwszy rzut oka i wymagają dodatkowego czasu :). A jeszcze lepiej gdybyś np. dodał plik txt z danymi wejściowymi, żeby ktoś mógł wykorzystać go w swoim programie (w celu pomocy Tobie).

0

Załączyłam moje dane wyjściowe w plikach txt. Dane macierzy głównej G znajdują się w pliku Full_data.txt, macierzy niepełnej m w pliku NotFull_data.txt. Chcę pomnożyć obie te macierze G x m w tym celu macierz m chce przekształcić do postaci mp: Expected_data.txt.

Do tej pory napisałam:

with open ('NotFull_data.txt', 'rb') as NotFull, open('Full_data.txt', 'rb') as Full:

for row1, row2 in zip(NotFull,Full):

    #for row1, row2 in range(8):

    if row1[0] == row2[0]:

        #print(row1)

        if row1[1] == row2[1]:

            if row1[2] == row2[2]:

                print(row1)

            else: #row1[2] != row2[2]:

                print (row1[0:5] == '0')

        else: # row1[1] != row2[1]:

            Full.next()

    else: # row1[1] != row2[1]:

        Full.next()

Ale nie działa jak powinno..

1

Serio rozpisz te macierze na kartce i zrób zdjęcie bo mi opis A a, A b nic nie mówi (macierz trójwymiarowa skoro A a ma pełny rząd, A a, B a też i to wszystko jest macierzą M?...)

for row1, row2 in zip(NotFull,Full):

Zip weźmie row1,row2 aż któreś z iterables się skończy (zapewne NotFull). No i dane będą "rozjechane" i to całe porównanie nie ma sensu. Najlepiej wczytaj dane osobno do macierzy a potem na tym operuj. Skoro masz zapis B b 1, B b 3.. w NotFull, który wprost sugeruje brak indexu 2. to możesz zrobić coś w deseń:

i = 0
values = []
for row in NotFull:
  x, y, index, row_data* = row.split()
  while(i!=index-1):
    #add zeros to values
    i+=1
  values.append(row_data)
  i = index

Oczywiście dochodzi porządkowanie danych (co dokładnie znaczy A a, Ba..) i ewentualne błędy w danych (różna długość row_data?).

0

Popieram przedmówcę. Rozpisz na kartce jak mają wyglądać dwie wejściowe macierze (wstaw tam jakieś losowe wartości) i pokaż jaki wynik mają dać. I nie wklejaj swoich kodów, bo tylko utrudniasz zrozumienie, o co Ci w ogóle chodzi.

0

Jak pisałam te macierze stworzyłam tylko pomocniczo. W rzeczywistości wartości ABC to są pierwiastki dla których badam czułość na różne reakcje chemiczne(abc) przy czym trzecia kolumna reprezentuje grupy enegetyczne dla jakich wykonano pomiar (1-3) a trzy ostatnie kolumny reprezentują wyniki (czułości) otrzymane przez inne źródła. Macierz G reprezentuje wyniki otrzymane na podstawie wielkiej bazy danych. Natomiast macierz m reprezentuje wyniki otrzymane przeze mnie lub jakieś inne osoby ( będę musiała wykonać pętlę w ktorej za macierz m przyjmę wiele innych przypadków).

0

Ok. I wynikiem ma być...? Cała ta otoczka czym to jest, jest nieważna. Na razie widzę macierz G(27, 3) i macierz m(22, 3). Masz wstawić wiersze z macierzy m do G, czy co?

0

Załączam zdjęcie

1

Widać nawet korzystania z forum dla programistów trzeba się nauczyć :)

0

Dziękuję za pomoc !

0

Niestety dalej nie mogę tego rozwiązać 😥 po pierwsze wlinijce w której rozdzielam wiersze pojawia się błąd, że jest za dużo danych do rozpakowania. No i też nie wiem jak zdefiniować last_index

0

Jak dłużej patrzę to zadanie ma trochę problematycznych spraw: index indeksuje dane Aa (np. Aa 1-3, Ba 1-4) więc może brakowac ostatniego indeksu w Aa i program tego nie wykryje (bo jest wiele róznych indeksów). Zaraz napiszę program który to zobrazuje i rozwiąże to

0

Kod pisany "na kolanie" i roboczo ale wynik zgadza się. Ostatecznie masz dostępną macierz G i M_n do dalszych obliczeń.

from collections import OrderedDict

def parseMatrix(path):
    with open(path, 'r') as f:
      matrix = []
      info = OrderedDict()
      for line in f:
        if not line:
          break
        info1, info2, index, *data = line.split()
        info[info1+info2+index] = 0 #I use ordereddict for perfomance over list
        matrix.append([int(c) for c in data])
      return info, matrix
      
info_g, G = parseMatrix('g.txt')
info_m, M = parseMatrix('m.txt')
row_len = 3

#print(G)
#print(info_g)

#print(M)
#print(info_m)

M_n = []
iterator = iter(M)

for row in info_g:
  if row in info_m:
    M_n.append(next(iterator))
  else:
    M_n.append([0]*row_len)

print(M_n)

pliki wejściowe:
g.txt:

A a 1 34 564 366
A a 2 643 0 6
A a 3 3 45 0
A b 1 0 0 45
A b 2 456 7 68
A b 3 57 23 0
A c 1 66 76 879
A c 2 787 0 435
A c 3 2 98 0
B a 1 12 43 789
B a 2 12 43 789
B a 3 57 57 97
B b 1 57 14 0
B b 2 36 897 2
B b 3 254 64 58
B c 1 254 64 58
B c 2 46 24 0
B c 3 46 79 32
C a 1 35 6 7
C a 2 436 68 2
C a 3 436 68 2
C b 1 356 0 6
C b 2 356 0 6
C b 3 345 7 57
C c 1 57 79 9
C c 2 57 79 9
C c 3 54 46 8

m.txt

A a 1 68 35 44
A a 2 77 91 48
A a 3 1 63 86
A b 1 52 31 25
A b 2 99 85 18
A b 3 47 74 19
A c 1 34 100 67
A c 2 44 68 92
A c 3 38 14 91
B a 1 9 84 27
B a 3 16 87 68
B b 1 78 84 38
B b 2 75 46 61
B b 3 79 89 48
B c 1 35 26 69
B c 2 92 93 88
C a 1 14 85 24
C a 2 62 69 66
C b 1 52 8 81
C b 3 91 44 37
C c 2 64 96 0
C c 3 40 33 7

Trzeba to ładniej napisać, zabiezpieczyć przed błędami w parsowaniu, dodać wyjątek na StopIteration (jeżeli nie ma już row w M a G wciąż ma) itp.

0

Okej, siadam analizy kodu. Dziękuję :)

0

Ale Ty wiesz, że przed mnożeniem musisz dokonać transpozycji?

0

Moje równanie jest znacznie bardziej skomplikowane. To tylko jeden z wielu kroków. Wiem, że trzeba dokonać transpozycji. Ogólnie nad numpy pogłowiłam już się trochę. Po prostu brakuje mi doświadczenia z programowaniem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1