2012-06-19 17 views
14

Mam wielowymiarową macierz (używając numpy), do której chciałbym dodać nagłówki kolumn/kolumn. Dane są rzeczywiście 7x12x12, ale mogę reprezentować to tak:Dodawanie nagłówków kolumn/wierszy do Numpy Matrices

A=[[[0, 1, 2, 3, 4, 5], 
     [1, 0, 3, 4, 5, 6], 
     [2, 3, 0, 5, 6, 7], 
     [3, 4, 5, 0, 7, 8], 
     [4, 5, 6, 7, 0, 9], 
     [5, 6, 7, 8, 9, 0]] 


    [[0, 1, 2, 3, 4, 5], 
     [1, 0, 3, 4, 5, 6], 
     [2, 3, 0, 5, 6, 7], 
     [3, 4, 5, 0, 7, 8], 
     [4, 5, 6, 7, 0, 9], 
     [5, 6, 7, 8, 9, 0]]] 

gdzie A jest moja macierz 2x6x6.

W każdym razie Jak wstawić nagłówki w całym pierwszym wierszu i pierwszej kolumnie, tak że każda matryca wygląda tak:

 A, a, b, c, d, e, f 
     a, 0, 1, 2, 3, 4, 5, 
     b, 1, 0, 3, 4, 5, 6, 
     c, 2, 3, 0, 5, 6, 7, 
     d, 3, 4, 5, 0, 7, 8, 
     e, 4, 5, 6, 7, 0, 9, 
     f, 5, 6, 7, 8, 9, 0 

w moim pliku wyjściowego csv?

W tej chwili zrobiłem matrycę 7x13x13 i wstawiłem dane takie, że mam wiersz i kolumnę 0, ale wolę ciągi. Chyba mógłbym napisać makro excela, aby zastąpić zera ciągami ... Problem polega na tym, że numpy nie może przekonwertować napisu na float, jeśli spróbuję ponownie przypisać te 0 jako żądane ciągi.

+0

Im nie znajomy z numpy ale byłoby to bardzo prosto dalej, jeśli były tylko listami. Czy rozwiązanie tego zamówienia byłoby dopuszczalne? czy możesz konwertować numpy matrice na listy? –

+0

Sposób w jaki pracują macierze numizmatyczne, mogą funkcjonować jako listy list, dzięki czemu można je samemu samemu dokładnie przetworzyć. – JAB

Odpowiedz

9

Numpy poradzi sobie z macierzą n-wymiarową, ale może z obiektów jest ograniczona do tablic dwuwymiarowych. Nie wiesz nawet, jak chcesz wyglądać plik wyjściowy.

Wiele osób, które życzyłyby sobie nazwanych kolumn, przeoczyło możliwości numpy w postaci recarray(). Dobre rzeczy do poznania, ale to tylko "wymienia" jeden wymiar.

Dla dwóch wymiarów, Pandas jest bardzo fajny.

In [275]: DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6])], 
    .....:      orient='index', columns=['one', 'two', 'three']) 
Out[275]: 
    one two three 
A 1 2  3 
B 4 5  6 

Jeśli wyjście jest tylko problem staramy się rozwiązać tutaj, pewnie po prostu trzymać się z kilku linii ręki zakodowanej magii, jak to będzie mniej groźne niż instalowanie kolejnego pakietu dla jednej cechy.

+0

Pandy są dokładnie tym, czego szukałem. – emmagras

1

Nie jestem świadomy żadnej metody dodawania nagłówków do macierzy (nawet jeśli uznałbym to za użyteczne). Chciałbym stworzyć małą klasę, która wypaliła obiekt dla mnie, przeciążając funkcję __str__.

coś takiego:

class myMat: 
    def __init__(self, mat, name): 
     self.mat = mat 
     self.name = name 
     self.head = ['a','b','c','d','e','f'] 
     self.sep = ',' 

    def __str__(self): 
     s = "%s%s"%(self.name,self.sep) 
     for x in self.head: 
      s += "%s%s"%(x,self.sep) 
     s = s[:-len(self.sep)] + '\n' 

     for i in range(len(self.mat)): 
      row = self.mat[i] 
      s += "%s%s"%(self.head[i],self.sep) 
      for x in row: 
       s += "%s%s"%(str(x),self.sep) 
      s += '\n' 
     s = s[:-len(self.sep)-len('\n')] 

     return s 

Następnie można po prostu łatwo wydrukować je z nagłówków, stosując następujący kod:

print myMat(A,'A') 
print myMat(B,'B') 
+0

To wygląda obiecująco. Próbując zdestabilizować moje pytanie, zdezorientowałem sprawy, ponieważ duża matryca w rzeczywistości nie składa się z mniejszych matryc oznaczonych etykietą. Próbowałem go podzielić i zaimplementować Twoją sugestię, ale nie działa. Na początek mam "indeks listy poza zakresem" w tym wierszu s + = "% s% s"% (self.head [i], self.sep) Jak zmieni się Twoja sugestia, biorąc pod uwagę, że A jest tylko macierz, zamiast radzić sobie z macierzą, która jest kompilacją macierzy? – emmagras

+0

Domyślam się, że otrzymałeś indeks poza zakresem błędu z powodu różnej wielkości matryc. Teraz ten kod działa tylko z macierzami 6x6 (tj. Len (["a", "b", "c", "d", "e", "f"])). Wystarczy zmienić linię, która definiuje self.head do rozmiaru macierzy (np. Jeśli macierze mają 3 x 3, linia powinna wyglądać jak self.head = ["a", "b", "c"]). Mam nadzieję że to pomoże! –

3

Pomyśl to załatwia sprawę rodzajowo

Wejście

mats = array([[[0, 1, 2, 3, 4, 5], 
    [1, 0, 3, 4, 5, 6], 
    [2, 3, 0, 5, 6, 7], 
    [3, 4, 5, 0, 7, 8], 
    [4, 5, 6, 7, 0, 9], 
    [5, 6, 7, 8, 9, 0]], 

    [[0, 1, 2, 3, 4, 5], 
    [1, 0, 3, 4, 5, 6], 
    [2, 3, 0, 5, 6, 7], 
    [3, 4, 5, 0, 7, 8], 
    [4, 5, 6, 7, 0, 9], 
    [5, 6, 7, 8, 9, 0]]]) 

Kod

# Recursively makes pyramiding column and row headers 
def make_head(n): 
    pre = '' 
    if n/26: 
     pre = make_head(n/26-1) 

    alph = "abcdefghijklmnopqrstuvwxyz" 
    pre+= alph[n%26] 
    return pre 

# Generator object to create header items for n-rows or n-cols 
def gen_header(nitems): 
    n = -1 
    while n<nitems: 
     n+=1 
     yield make_head(n) 

# Convert numpy to list 
lmats = mats.tolist() 

# Loop through each "matrix" 
for mat in lmats: 
    # Pre store number of columns as we modify it before working rows 
    ncols = len(mat[0]) 

    # add header value to front of each row from generator object 
    for row,hd in zip(mat,gen_header(len(mat))): 
     row.insert(0,hd) 

    # Create a "header" line for all the columns 
    col_hd = [hd for hd in gen_header(ncols-1)] 
    col_hd.insert(0,"A") 

    # Insert header line into lead row of matrix 
    mat.insert(0,col_hd) 

# Convert back to numpy 
mats = numpy.array(lmats) 

Output (wartość przechowywana w matach):

array([[['A', 'a', 'b', 'c', 'd', 'e', 'f'], 
     ['a', '0', '1', '2', '3', '4', '5'], 
     ['b', '1', '0', '3', '4', '5', '6'], 
     ['c', '2', '3', '0', '5', '6', '7'], 
     ['d', '3', '4', '5', '0', '7', '8'], 
     ['e', '4', '5', '6', '7', '0', '9'], 
     ['f', '5', '6', '7', '8', '9', '0']], 

     [['A', 'a', 'b', 'c', 'd', 'e', 'f'], 
     ['a', '0', '1', '2', '3', '4', '5'], 
     ['b', '1', '0', '3', '4', '5', '6'], 
     ['c', '2', '3', '0', '5', '6', '7'], 
     ['d', '3', '4', '5', '0', '7', '8'], 
     ['e', '4', '5', '6', '7', '0', '9'], 
     ['f', '5', '6', '7', '8', '9', '0']]], 
     dtype='|S4') 
+0

Występuje błąd "Obiekt" numpy.ndarray "nie ma atrybutu" wstaw "" Wszelkie sugestie dotyczące obejścia? – emmagras

+0

Obejmij pracę. Przekształciłem maty numpy na listy, wykonałem operacje i dokonałem konwersji z powrotem. Procedury wstawiania Numpy są dość głupie lub nie widzę, jak są przydatne. –

+0

Dziękuję. W końcu to rozgryzłem. – emmagras

1

Nie bardzo wiadomo, ale można rozważyć zaglądając do Pandas.

21

Z pandas.DataFrame.to_csv można napisać kolumny i indeks do pliku:

import numpy as np 
import pandas as pd 

A = np.random.randint(0, 10, size=36).reshape(6, 6) 
names = [_ for _ in 'abcdef'] 
df = pd.DataFrame(A, index=names, columns=names) 
df.to_csv('df.csv', index=True, header=True, sep=' ') 

dadzą Ci następujące df.csv plik:

a b c d e f 
a 1 5 5 0 4 4 
b 2 7 5 4 0 9 
c 6 5 6 9 7 0 
d 4 3 7 9 9 3 
e 8 1 5 1 9 0 
f 2 8 0 0 5 1  
+1

Jest to szczególnie przydatne, ponieważ zawiera polecenia importu i informacje o tym, jak pisać do pliku. Niesamowite. – emmagras

+0

Dzięki. Jeśli powiesz, że moja odpowiedź jest niesamowita, rozważ ją, aby ją upomnieć ;-) – bmu

Powiązane problemy