继续这个问题:
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
如果可能,我想使用字段名称。我在这里做错了什么?
非常感谢。
答案 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专家...也许是最不熟练的专家之一