我有一个NumPy
ndarray
,我想添加行/列标题。
数据实际上是7x12x12,但我可以这样表示:
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]]]
其中A是我的2x6x6阵列。
如何在第一行和第一列中插入标题,以便我的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
现在,我所做的是使数组7x13x13并插入数据,使得我有一行零列,但我更喜欢字符串。
我想我可以写一个Excel宏来用字符串替换零。但问题是NumPy
无法将string
转换为float
,如果我尝试将这些零重新分配为我想要的字符串。
答案 0 :(得分:30)
使用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 :(得分:13)
Numpy将处理n维数组的罚款,但可能的设施仅限于二维数组。甚至不确定您希望输出文件的外观。
许多希望使用命名列的人忽略了numpy的recarray()功能。要知道的好东西,但只是“命名”一个维度。
对于两个维度,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
如果输出是你在这里尝试解决的唯一问题,我可能会坚持使用几行手写魔术,因为它比为一个功能安装另一个包的重量要小。
答案 2 :(得分:3)
认为这是一般的伎俩
输入
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')
答案 3 :(得分:2)
不太确定,但您可以考虑查看Pandas。
答案 4 :(得分: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')