2012-06-19 6 views
14

У меня есть многомерная матрица (с использованием numpy), к которой я хотел бы добавить заголовки столбцов/столбцов. Данные на самом деле 7x12x12, но я могу представить это следующим образом:Добавление заголовков столбцов/столбцов в матрицы Numpy

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

где А мой 2x6x6 матрицу.

В любом случае, Как вставить заголовки всей первой строки и первого столбца, так что каждая матрица выглядит следующим образом:

 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 

в моем выходном файле CSV?

Теперь я сделал матрицу 7x13x13 и вставил данные так, что у меня есть строка и столбец из 0, но я бы предпочел строки. Думаю, я мог бы написать макрос excel, чтобы заменить нули на строки ... Проблема в том, что numpy не может преобразовать строку в float, если я попытаюсь переназначить эти 0 как строки, которые я хочу.

+0

Я не знаком с NumPy, но это было бы очень прямой если они были просто списками. Будет ли решение этого порядка приемлемым? можете ли вы преобразовать матрицы numpy в списки? –

+0

Как работают матричные матрицы, они могут функционировать как списки списков, поэтому вы можете перебирать их просто отлично. – JAB

ответ

9

Numpy будет обрабатывать мелкие размеры n-мерного массива, но возможности объектов ограничены 2-мерными массивами. Даже не уверен, как вы хотите, чтобы выходной файл выглядел.

Многие люди, которые хотели бы назвать названные столбцы, видятвозможности numpy. Хорошие вещи, чтобы знать, но только «имена» одного измерения.

Для двух измерений, Pandas очень круто.

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 

Если выход единственная проблема, вы пытаетесь решить здесь, я бы, наверное, просто придерживаться нескольких строк ручной кодированной магии, как это будет менее весомым, чем установка другого пакета для одной функции.

+0

Pandas - именно то, что я искал. – emmagras

1

Мне неизвестен какой-либо метод добавления заголовков в матрицу (хотя я считаю это полезным). Я бы сделал, чтобы создать небольшой класс, который печатает объект для меня, перегружая функцию __str__.

Что-то вроде этого:

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 

Тогда вы можете просто легко распечатать их с заголовками, используя следующий код:

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

Это выглядит многообещающим. Пытаясь отвлечь мой вопрос, я смутил вопросы, поскольку большая матрица на самом деле не состоит из помеченных меньших матриц. Я попытался разделить его и реализовать ваше предложение, но оно не работает. Для начала у меня есть «индекс списка вне диапазона» в этой строке s + = «% s% s»% (self.head [i], self.sep) Как бы ваше предложение изменилось, учитывая, что A является только матрица, вместо того, чтобы иметь дело с матрицей, являющейся компиляцией матриц? – emmagras

+0

Я предполагаю, что вы получаете индекс из диапазона ошибок из-за разного размера матриц. Прямо сейчас этот код будет работать только с матрицами 6x6 (то есть len (['a', 'b', 'c', 'd', 'e', ​​'f'])). Просто измените строку, определяющую self.head, на размер вашей матрицы (например, если ваши матрицы 3x3, строка должна выглядеть как self.head = ['a', 'b', 'c']). Надеюсь это поможет! –

3

Думаю, что это делает трюк обобщенно

Input

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

Код

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

выход (значение, сохраненное в матах):

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

Я получаю сообщение об ошибке '' numpy.ndarray 'объект не имеет атрибута' insert'' Любые предложения обходных решений? – emmagras

+0

Работа вокруг включены. Я преобразовал числовые маты в списки, выполнив операции и преобразованные обратно. Процедуры вставки Numpy довольно глупы или я не вижу, как они полезны. –

+0

Спасибо. В конце концов, я понял это. – emmagras

1

Не совсем уверен, но вы можете рассмотреть возможность взглянуть на Pandas.

21

С pandas.DataFrame.to_csv вы можете написать столбцы и индекс к файлу:

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

даст вам следующий df.csv файл:

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

Это особенно полезно, поскольку в нем содержатся команды импорта и информация о том, как писать в файл. Потрясающие. – emmagras

+0

Спасибо. Если вы скажете, что мой ответ потрясающий, подумайте над этим ;-) – bmu

Смежные вопросы