0

我有一个元组列表,例如:

l=[ (2,2,1), (2,4,0), (2,8,0),
    (4,2,0), (4,4,1), (4,8,0),
    (8,2,0), (8,4,0), (8,8,1) ]

并想将其转换为这样的numpy数组(矩阵中只有z值,对应x,y坐标的序列,坐标应单独存储):

array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])

我在下面发布了我的解决方案,但它非常低级,我认为应该有一些更高级别的解决方案,或者使用 matplotlib 或 numpy。任何的想法?

需要这种转换来为 matplotlib 绘图函数(如pcolorimshowcontour.

4

4 回答 4

2

看起来带有该选项的np.uniquereturn_inverse符合要求。例如,

In [203]: l[:,0]
Out[203]: array([2, 2, 2, 4, 4, 4, 8, 8, 8])

In [204]: np.unique(l[:,0], return_inverse = True)
Out[204]: (array([2, 4, 8]), array([0, 0, 0, 1, 1, 1, 2, 2, 2]))

np.unique返回一个 2 元组。2 元组中的第一个数组是一个包含所有唯一值的数组l[:,0]。第二个数组是将值array([2, 4, 8])与原始数组中的值相关联的索引值l[:,0]。它也恰好是排名,因为np.unique按排序顺序返回唯一值。


import numpy as np
import matplotlib.pyplot as plt

l = np.array([ (2,2,1), (2,4,0), (2,8,0),
               (4,2,0), (4,4,1), (4,8,0),
               (8,2,0), (8,4,0), (8,8,1) ])

x, xrank = np.unique(l[:,0], return_inverse = True)
y, yrank = np.unique(l[:,1], return_inverse = True)

a = np.zeros((max(xrank)+1, max(yrank)+1))
a[xrank,yrank] = l[:,2]

fig = plt.figure()
ax = plt.subplot(111)

ax.pcolor(x, y, a)   
plt.show()

产量

在此处输入图像描述

于 2012-11-04T18:25:36.370 回答
0

我的解决方案首先对 x 和 y 值进行排序,然后创建数组。

l=[ (2,2,1), (2,4,0), (2,8,0),
    (4,2,0), (4,4,1), (4,8,0),
    (8,2,0), (8,4,0), (8,8,1) ]

def rankdata_ignoretied(data):
   """ranks data counting all tied values as one"""
   # first translate the data values to integeres in increasing order
   counter=0
   encountered=dict()
   for e in sorted(data):
      if e not in encountered:
         encountered[e]=counter
         counter+=1   
   # then map the original sequence of the data values
   result=[encountered[e] for e in data]
   return result

x=[e[0] for e in l]
y=[e[1] for e in l]
z=[e[2] for e in l]

xrank=rankdata_ignoretied(x)
yrank=rankdata_ignoretied(y)

import numpy
a=numpy.zeros((max(xrank)+1, max(yrank)+1))
for i in range(len(l)):
   a[xrank[i],yrank[i]]=l[i][2]

要使用生成的数组进行绘图,还需要原始 x 和 y 值,例如:

ax=plt.subplot(511)
ax.pcolor(sorted(set(x)), sorted(set(y)), a)

任何人都对如何实现这一目标有更好的了解?

于 2012-11-04T18:14:17.680 回答
0

我不明白你为什么要把这个弄得这么复杂。你可以简单地做到这一点:

array([
    [cell[2] for cell in row] for row in zip(*[iter(x)] * 3)
])

或者也许更易读:

array([
    [a[2], b[2], c[2]] for a, b, c in zip(x[0::3], x[1::3], x[2::3])
])
于 2012-11-04T18:26:35.757 回答
0

使用标准 python 构造集、列表和排序的解决方案。如果您没有很多积分,即使比 unutbu 给出的 numpy 解决方案慢,它也会提高可读性

l=[ (2,2,1), (2,4,0), (2,8,0),
    (4,2,0), (4,4,1), (4,8,0),
    (8,2,0), (8,4,0), (8,8,1) ]

#get the ranks of the values for x and y
xi = sorted(list(set( i[0] for i in l )))
yi = sorted(list(set( i[1] for i in l )))
a = np.zeros((len(xi),len(yi)))
#fill the matrix using the list.index
for x,y,v in l:
    a[xi.index(x),yi.index(y)]=v

ax=plt.subplot(111)
ax.pcolor(array(xi), array(yi), a)
于 2012-11-04T18:34:59.783 回答