J'ai un NumPy
ndarray
auquel j'aimerais ajouter des en-têtes de ligne/colonne.
Les données sont en fait 7x12x12, mais je peux les représenter comme ceci:
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]]]
où A est ma matrice 2x6x6.
Comment insérer des en-têtes sur la première ligne et la première colonne, de sorte que chaque tableau ressemble à ceci dans mon fichier de sortie CSV
?
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
En ce moment, ce que j'ai fait est de créer le tableau 7x13x13 et d'insérer les données de sorte que j'ai une ligne et une colonne de zéros, mais je préférerais de loin les chaînes.
Je suppose que je pourrais simplement écrire une macro Excel pour remplacer les zéros par des chaînes. Cependant, le problème est que NumPy
ne peut pas convertir string
en float
, si j'essaye de réaffecter ces zéros comme chaînes que je veux.
Numpy gérera très bien les tableaux à n dimensions, mais peut-être que les installations sont limitées à des tableaux à 2 dimensions. Je ne sais même pas à quoi vous voulez que le fichier de sortie ressemble.
Beaucoup de gens qui souhaiteraient des colonnes nommées négligent les capacités recarray () de numpy. Bon à savoir mais qui ne "nomme" qu'une dimension.
Pour deux dimensions, Pandas est très 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
Si la sortie est le seul problème que vous essayez de résoudre ici, je m'en tiendrai probablement à quelques lignes de magie codée à la main car cela sera moins lourd que d'installer un autre package pour une fonctionnalité.
Avec pandas.DataFrame.to_csv
vous pouvez écrire les colonnes et l'index dans un fichier:
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=' ')
vous donnera les éléments suivants df.csv
fichier:
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
Je pense que cela fait l'affaire de manière générique
Contribution
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
# 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)
Sortie (valeur stockée dans des tapis):
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')
Pas vraiment sûr, mais vous pouvez envisager de consulter Pandas .
Je ne connais aucune méthode pour ajouter des en-têtes à la matrice (même si je la trouverais utile). Ce que je ferais, c'est de créer une petite classe qui imprime l'objet pour moi, surchargeant le __str__
une fonction.
Quelque chose comme ça:
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
Ensuite, vous pouvez facilement les imprimer avec les en-têtes, en utilisant le code suivant:
print myMat(A,'A')
print myMat(B,'B')