【问题标题】:Creating numpy array from dict从dict创建numpy数组
【发布时间】:2015-11-11 18:46:49
【问题描述】:

假设我有一个字典,称之为coeffs

coeffs = {'X1': 0.1, 'X2':0.2, 'X3':0.4, ..., 'Xn':0.09}

如何将值转换为 1 x n ndarray

变成 n x m ndarray?

【问题讨论】:

  • 我们也很困惑,因为你没有解释你想要什么。从字典中获取值列表和从中获取数组很容易。但这对字典键没有任何作用。
  • @hpaulj “如何将值转换为 1 x n 数组”不是对我想要做什么的解释?并非本网站上的所有人都是 python 专家...
  • 我猜你希望coeffs['X1'] 成为列表中的第一个项目,coeffs['Xn'] 第 n 个。但我更希望你明确说明这种细节。我仍然不知道这些数据的 nxm 数组会是什么样子。
  • @GPB:一方面,我不知道X 后面的数字应该是索引。应该很清楚,但是...
  • @user - 点。但是我记下它的方式,我认为这并不重要。

标签: python arrays numpy dictionary


【解决方案1】:

这是一个使用 coeffs 填充数组的示例,其值索引源自字典键:

In [591]: coeffs = {'X1': 0.1, 'X2':0.2, 'X3':0.4, 'X4':0.09}
In [592]: alist = [[int(k[1:]),v] for k,v in coeffs.items()]
In [593]: alist
Out[593]: [[4, 0.09], [3, 0.4], [1, 0.1], [2, 0.2]]

在这里,我去掉了初始字符并将其余字符转换为整数。您可以自己进行转换。

现在只需初始化一个空数组,然后填写值:

In [594]: X = np.zeros((5,))
In [595]: for k,v in alist: X[k] = v
In [596]: X
Out[596]: array([ 0.  ,  0.1 ,  0.2 ,  0.4 ,  0.09])

显然我可以使用X = np.zeros((1,5))(n,m) 数组没有意义,除非有为每个字典项选择 n 的基础。


只是为了笑,这是从字典中创建数组的另一种方法 - 将键和值放入结构化数组的字段中:

In [613]: X = np.zeros(len(coeffs),dtype=[('keys','S3'),('values',float)])
In [614]: X
Out[614]: 
array([(b'', 0.0), (b'', 0.0), (b'', 0.0), (b'', 0.0)], 
      dtype=[('keys', 'S3'), ('values', '<f8')])
In [615]: for i,(k,v) in enumerate(coeffs.items()):
    X[i]=(k,v)
   .....:     
In [616]: X
Out[616]: 
array([(b'X4', 0.09), (b'X3', 0.4), (b'X1', 0.1), (b'X2', 0.2)], 
      dtype=[('keys', 'S3'), ('values', '<f8')])
In [617]: X['keys']
Out[617]: 
array([b'X4', b'X3', b'X1', b'X2'], 
      dtype='|S3')
In [618]: X['values']
Out[618]: array([ 0.09,  0.4 ,  0.1 ,  0.2 ])

scipysparse 模块采用稀疏矩阵格式,将其值存储在字典中,实际上它是字典的子类。该字典中的键是(i,j) 元组,即非零元素的索引。 Sparse 具有将此类矩阵快速转换为其他计算更友好的稀疏格式以及常规密集数组的工具。

我在其他 SO 问题中了解到,构建此类矩阵的快速方法是使用常规字典 update 方法从另一个字典复制值。

@user's 这个问题的 2d 版本的启发,下面是如何创建这样一个稀疏矩阵的方法。

@user's 示例coeffs 开始:

In [24]: coeffs
Out[24]: 
{'Y8': 22,
 'Y2': 16,
 'Y6': 20,
 'X5': 20,
 'Y9': 23,
 'X2': 17,
  ...
 'Y1': 15,
 'X4': 19}

定义一个小函数,将键的X3 样式转换为(0,3) 样式:

In [25]: def decodekey(akey):
    pt1,pt2 = akey[0],akey[1:]
    i = {'X':0, 'Y':1}[pt1]
    j = int(pt2)
    return i,j
   ....: 

通过字典推导将其应用于coeffs(或在早期 Python 版本中使用常规循环):

In [26]: coeffs1 = {decodekey(k):v for k,v in coeffs.items()}
In [27]: coeffs1
Out[27]: 
{(1, 2): 16,
 (0, 1): 16,
 (0, 0): 15,
 (1, 4): 18,
 (1, 5): 19,
 ...
 (0, 8): 23,
 (0, 2): 17}

导入sparse并定义一个空的dok矩阵:

In [28]: from scipy import sparse
In [29]: M=sparse.dok_matrix((2,10),dtype=int)
In [30]: M.A
Out[30]: 
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

coeffs1 字典值填充它:

In [31]: M.update(coeffs1)
In [33]: M.A   # convert to dense array
Out[33]: 
array([[15, 16, 17, 18, 19, 20, 21, 22, 23, 24],
       [14, 15, 16, 17, 18, 19, 20, 21, 22, 23]])

其实我不需要用sparsecoeffs1 转换成数组。 (i,j) 元组可以直接索引一个数组,A[(i,j)]A[i,j] 相同。

In [34]: A=np.zeros((2,10),int)
In [35]: for k,v in coeffs1.items():
   ....:     A[k] = v
   ....:     
In [36]: A
Out[36]: 
array([[15, 16, 17, 18, 19, 20, 21, 22, 23, 24],
       [14, 15, 16, 17, 18, 19, 20, 21, 22, 23]])

【讨论】:

  • 将数字解释为索引很好。请参阅下面的 nxm 解决方案。 (有进一步解释)
  • 我找到了几种创建 2 行数组的方法。一旦像 'X3' 这样的键被转换为像 (0,3) 这样的元组,创建一个数组几乎是微不足道的。
【解决方案2】:

关于n x m 数组

@hpaulj's answer 假设(正确地)X 之后的数字应该是位置。如果你有类似的数据

coeffs = {'X1': 3, 'X2' : 5, ..., 'Xn' : 34, 'Y1': 5, 'Y2' : -3, ..., 'Yn': 32}

您可以执行以下操作。给定样本数据,如

{'Y3': 17, 'Y2': 16, 'Y8': 22, 'Y5': 19, 'Y6': 20, 'Y4': 18, 'Y9': 23, 'Y1': 15, 'X8': 23, 'X9': 24, 'Y7': 21, 'Y0': 14, 'X2': 17, 'X3': 18, 'X0': 15, 'X1': 16, 'X6': 21, 'X7': 22, 'X4': 19, 'X5': 20}

创建者

a = {}
for i in range(10):
    a['X'+str(i)] = 15 + i
for i in range(10):
    a['Y'+str(i)] = 14 + i 

把它放在一些有序的字典中(效率低,但容易)

b = {}
for k, v in a.iteritems():
    letter = k[0]
    index = float(k[1:])
    if letter not in b.keys():
        b[letter] = {}
    b[letter][index] = v

给予

>>> b
{'Y': {0: 14, 1: 15, 2: 16, 3: 17, 4: 18, 5: 19, 6: 20, 7: 21, 8: 22, 9: 23}, 'X': {0: 15, 1: 16, 2: 17, 3: 18, 4: 19, 5: 20, 6: 21, 7: 22, 8: 23, 9: 24}}

找出数组的目标尺寸。 (这假设所有参数的长度相同,并且您已经给出了所有值)。

row_length = max(b.values()[0])
row_indices = b.keys()
row_indices.sort()

通过

创建数组
X = np.empty((len(b.keys()), max(b.values()[0])))

并插入数据:

for i,row in enumerate(row_indices):
    for j in range(row_length):
        X[i,j] = b[row][j]

结果

>>> X
array([[ 15.,  16.,  17.,  18.,  19.,  20.,  21.,  22.,  23.],
       [ 14.,  15.,  16.,  17.,  18.,  19.,  20.,  21.,  22.]])

旧答案

coeffs.values() 是字典值的数组。只需创建一个

np.array(coeffs.values())

一般来说,当你有coeffs这样的对象时,你可以输入

help(coeffs) 

在解释器中,获取它可以做的所有事情的列表。

【讨论】:

  • Tnx...看起来很明显。也许这就是为什么有人反对我的问题?
  • 不太明显的是值如何在数组中排序。从上面的字典值创建一个数组似乎打乱了字典的顺序。这是怎么做到的?
  • @GPB:没有保证顺序(除非您不更改字典,否则顺序始终相同:stackoverflow.com/questions/835092/…)。如果您需要广告订单,请使用docs.python.org/2/library/…
  • @GPB:(重新投票)有时它们是随机的。可能有帮助的是 1) 展示研究成果(说出您尝试过的内容) 2) 您的代码已被编辑(由我提议)以遵循命名约定。有时也有帮助 3) 1 次赞成“值得”一些反对。
  • - re: 2) “展示研究努力”很难证明,是吗?我找了多久?一个很好的30分钟。我猜这个评论暗示我比大多数人都厚。不确定做了什么编辑。
猜你喜欢
  • 1970-01-01
  • 2017-12-30
  • 2013-11-28
  • 1970-01-01
  • 2021-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-07
相关资源
最近更新 更多