将numpy数组字段中的行与列表相乘

时间:2014-11-23 09:17:43

标签: python arrays numpy

继续这个问题:

Unexpectedly large array created with numpy.ones when setting names

当我乘以

a = np.ones([len(sectors),len(columns)])
a[0,:] *= [1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8] 

工作正常。

当我尝试

columns = ["Port Wt", "Bench Wt", "Port Retn", "Bench Retn", 
            "Attrib", "Select", "Inter", "Total"]
a = np.ones((10,), dtype={"names":columns, "formats":["f8"]*len(columns)})
a[0] *= [1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8]

我收到错误

TypeError: cannot convert to an int; scalar object is not a number

如果可能,我想使用字段名称。我在这里做错了什么?

非常感谢。

2 个答案:

答案 0 :(得分:2)

可以通过为a指定tuple来修改此In [162]: a = np.ones((10,), dtype={"names":columns, "formats":["f8"]*len(columns)}) In [163]: x=[1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8] In [164]: a[0]=tuple(np.array(x)*list(a[0])) In [165]: a Out[165]: array([(1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8), ...], dtype=[('Port Wt', '<f8'), ('Bench Wt', '<f8'),... 的元素(行)。我们可以利用列表轻松转换为数组和从数组转换的事实,写入:

a[i] = tuple(foo(list(a[i]))

更普遍的是你可以写

a

可以使用元组列表设置data的多个值('行')。

早期的SO结构数组问题(https://stackoverflow.com/a/26183332/901925)提出了另一种解决方案 - 创建一个共享相同In [311]: a1 = np.empty((10,8)) # conventional 2d array In [312]: a1.data = a.data # share the a's data buffer In [313]: a1[0] *= x # do math on a1 In [314]: a1 Out[314]: array([[ 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8], ... [ 1. , 1. , 1. , 1. , 1. , 1. , 1. , 1. ]]) In [315]: a Out[315]: array([(1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8), ... (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)], dtype=[('Port Wt', '<f8'), ('Bench Wt', '<f8'), ('Port Retn', '<f8'), ('Bench Retn', '<f8'), ('Attrib', '<f8'), ('Select', '<f8'), ('Inter', '<f8'), ('Total', '<f8')]) 缓冲区的伙伴2d数组。

data

通过共享a1缓冲区,对a所做的更改也会影响a1

最好将2d a视为主数组,将a视为结构化视图。可以根据需要动态构建csv,以显示数据,按名称访问列或写入{{1}}文件。

答案 1 :(得分:1)

数组a 的行不是 numpy的数组,最接近它们的可能是元组

>>> import numpy as np
>>> columns = ["Port Wt", "Bench Wt", "Port Retn", "Bench Retn", 
...            "Attrib", "Select", "Inter", "Total"]
>>> a = np.ones((10,), dtype={"names":columns, "formats":["f8"]*len(columns)})
>>> type(a[0,0])
IndexError: too many indices
>>> type(a[0][0])
numpy.float64
>>> type(a[0])
numpy.void
>>> 

相反,a的列是ndarray的,你可以将它们乘以一个正确长度的浮点列表(不是列的nuber,而是行数)

>>> type(a['Select'])
numpy.ndarray
>>> a['Select']*[1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-27-fc8dc4596098> in <module>()
----> 1 a['Select']*[1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8]

ValueError: operands could not be broadcast together with shapes (10,) (8,) 
>>> a['Select']*[1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,       0,0]
array([ 1.1,  1.2,  1.3,  1.4,  1.5,  1.6,  1.7,  1.8,  0. ,  0. ])
>>> 

修改

回应OP的评论:«是否无法将函数应用于numpy中命名的字段(或元组)数组中的行?»

我所知道的唯一方法是

>>> a[0] = tuple(b*a[c][0] for b, c in zip([1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8],columns))
>>> print a
[(1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8)
 (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
 (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
 (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
 (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
 (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
 (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
 (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
 (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
 (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)]
>>> 

但我不是最熟练的numpy专家...也许是最不熟练的专家之一