2012-06-19 24 views
14

Ich habe eine multidimensionale Matrix (mit numpy), zu der ich Zeilen-/Spaltenköpfe hinzufügen möchte. Die Daten sind tatsächlich 7x12x12, aber ich kann es wie folgt darstellen:Zeilen-/Spaltenköpfe zu Numpy-Matrizen hinzufügen

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

wo A meine 2x6x6 Matrix ist.

In jedem Fall Wie füge ich Header über der ersten Reihe und der ersten Spalte, so dass jede Matrix wie folgt aussieht: Datei

 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 

in meiner CSV-Ausgabe?

Im Moment habe ich die Matrix 7x13x13 gemacht und die Daten so eingefügt, dass ich eine Zeile und eine Spalte von Nullen habe, aber ich bevorzuge Strings. Ich denke, ich könnte einfach ein Excel-Makro schreiben, um die Nullen durch Strings zu ersetzen ... Das Problem ist, dass numpy String nicht in Float konvertieren kann, wenn ich versuche, diese Nullen als die Strings, die ich will, neu zuzuweisen.

+0

Im nicht vertraut mit numpy aber das wäre sehr gerade Weiterleiten, wenn sie nur Listen waren. Wäre eine Lösung dieser Reihenfolge akzeptabel? Können Sie numpy Matrizen in Listen umwandeln? –

+0

Die Art wie numpy Matrizen funktionieren, können sie als Listen von Listen funktionieren, so dass Sie einfach über sie selbst iterieren können. – JAB

Antwort

9

Numpy behandelt n-dimensionale Arrays in Ordnung, aber die Möglichkeiten sind auf zweidimensionale Arrays beschränkt. Nicht einmal sicher, wie die Ausgabedatei aussehen soll.

Viele Leute, die sich für benannte Spalten wünschen, übersehen die recarray() Fähigkeiten von numpy. Gute Dinge zu wissen, aber das "benennt" nur eine Dimension.

Für zwei Dimensionen ist Pandas sehr cool.

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 

Wenn Ausgang das einzige Problem ist, dass Sie hier versuchen zu lösen, würde ich wahrscheinlich mit ein paar Zeilen von Hand codiert Magie-Stick genauso wie es weniger gewichtig sein wird, ein anderes Paket für eine Funktion als die Installation.

+0

Pandas ist genau das, was ich gesucht habe. – emmagras

1

Mir ist keine Methode bekannt, Kopfzeilen zur Matrix hinzuzufügen (obwohl ich es nützlich finden würde). Ich würde eine kleine Klasse erstellen, die das Objekt für mich druckt und die __str__-Funktion überlädt.

Etwas wie folgt aus:

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 

Dann könnte man nur leicht sie mit den Überschriften drucken, mit dem folgenden Code:

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

Das sieht vielversprechend aus. Beim Versuch, meine Frage aufzuschlüsseln, verwirrte ich die Dinge, da die große Matrix nicht wirklich aus beschrifteten kleineren Matrizen besteht. Ich habe versucht, es zu teilen und Ihren Vorschlag zu implementieren, aber es funktioniert nicht. Für den Anfang habe ich einen "Listenindex außerhalb des Bereichs" in dieser Zeile s + = "% s% s"% (self.head [i], self.sep) Wie würde sich Ihr Vorschlag ändern, wenn man bedenkt, dass A der ist nur Matrix, anstatt mit einer Matrix zu arbeiten, die eine Zusammenstellung von Matrizen ist? – emmagras

+0

Ich vermute, dass Sie einen Index außerhalb des Bereichs Fehler aufgrund unterschiedlicher Größe der Matrizen erhalten. Im Moment funktioniert dieser Code nur mit 6x6 Matrizen (d. H. Len (['a', 'b', 'c', 'd', 'e', ​​'f'])). Ändern Sie einfach die Zeile, die self.head definiert, zu Ihrer Matrixgröße (wenn Ihre Matrizen beispielsweise 3x3 sind, sollte die Zeile wie self.head = ['a', 'b', 'c'] aussehen). Hoffe das hilft! –

3

Ich glaube, das funktioniert der Trick allgemein

Eingang

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

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

Ausgang (Wert in Matten gespeichert):

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

Ich erhalte einen Fehler '' numpy.darray 'Objekt hat kein Attribut' insert'' Alle Umgehungsvorschläge? – emmagras

+0

Work around inklusive. Ich habe die numpy Matten zu Listen konvertiert, die Operationen ausgeführt und zurück konvertiert. Numpy einfügen Routinen sind ziemlich dumm oder ich sehe nicht, wie sie nützlich sind –

+0

Vielen Dank. Ich habe es schließlich herausgefunden. – emmagras

1

Nicht wirklich sicher, aber Sie können auf Pandas einen Blick betrachten zu müssen.

21

Mit pandas.DataFrame.to_csv können Sie die Spalten und den Index in eine Datei schreiben:

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=' ') 

wird Ihnen die folgende df.csv Datei:

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

Dies ist besonders hilfreich, da es die Importbefehle und Informationen zum Schreiben in eine Datei enthält. Genial. – emmagras

+0

Danke. Wenn Sie sagen, dass meine Antwort großartig ist, ziehen Sie es in Betracht. – bmu