我或许应该先对你的“无法工作”表述提出疑问,等待你提供更多具体问题的详情。不过,让我们先检验一下你的代码。
首先查看 x
数组的内容:
In [290]: x
Out[290]:
array([['circle', 'north', 'red', 'long', '0'],
['circle', 'north', 'red', 'short', '0'],
['circle', 'north', 'blue', 'long', '0'],
['circle', 'north', 'blue', 'short', '0'],
['circle', 'south', 'red', 'long', '0'],
['circle', 'south', 'red', 'short', '0'],
...
['square', 'south', 'blue', 'short', '0']], dtype='<U11')
In [291]: x.shape
Out[291]: (16, 5)
这是一个二维数组,具有5列——前4列是你所定义的标签列,最后一列是附加的字符串形式的 "0"。
而当你尝试使用 np.where
函数时,它对此提出了异议:
···Python
In [292]: np.where((x[:,0]=='circle') & (x[:,1]=='south'), x[:,4]+1, 2)
UFuncTypeError: ufunc 'add' did not contain a loop with signature matching types (dtype('<U11'), dtype('int32')) > None
In [293]: x[:,4]
Out[293]:
array(['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'0', '0', '0'], dtype='<U11')
一个充满字符串的数组在其所有列中都将包含字符串值。
我们可以通过首先将这些字符串转换为整数来完成计算:
```Python
In [295]: np.where((x[:,0]=='circle') & (x[:,1]=='south'), x[:,4].astype(int)+1, 2)
Out[295]: array([2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2])
但是,当这些数字被赋值回数组时,它们将会被转换回字符串形式。
In [296]: x[:,4] = np.where((x[:,0]=='circle') & (x[:,1]=='south'), x[:,4].astype(int)+1, 2)
In [297]: x[:,4]
Out[297]:
array(['2', '2', '2', '2', '1', '1', '1', '1', '2', '2', '2', '2', '2',
'2', '2', '2'], dtype='<U11')
只要你记住这一点,在后续的工作中就不应该会有问题。
使用 pandas
使用 pandas
,很容易创建一个包含混合数据类型的框架。从列表的列表(而不是数组)开始:
In [301]: a = ['circle','square']
...: b=['north','south']
...: c=['red','blue']
...: d=['long','short']
...: x = []
...: for shape in a:
...: for direction in b:
...: for color in c:
...: for length in d:
...: x.append([shape, direction, color, length, 0])
...:
In [302]: x
Out[302]:
[['circle', 'north', 'red', 'long', 0],
['circle', 'north', 'red', 'short', 0],
['circle', 'north', 'blue', 'long', 0],
...
['square', 'south', 'blue', 'short', 0]]
In [303]: df=pd.DataFrame(x)
In [304]: df
Out[304]:
0 1 2 3 4
0 circle north red long 0
1 circle north red short 0
2 circle north blue long 0
...
15 square south blue short 0
In [305]: df.dtypes
Out[305]:
0 object
1 object
2 object
3 object
4 int64
dtype: object
</code></pre>
<p>The <code>where</code> can now work directly with the 4th numeric column:</p>
<pre><code>In [307]: np.where((df[0]=='circle') & (df[1]=='south'), df[4]+1, 2)
Out[307]: array([2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2], dtype=int64)
In [308]: df[4]=np.where((df[0]=='circle') & (df[1]=='south'), df[4]+1, 2)
In [309]: df
Out[309]:
0 1 2 3 4
0 circle north red long 2
1 circle north red short 2
2 circle north blue long 2
....
numpy
也允许在结构化数组中使用混合数据类型,但如果你能使用 pandas
,可能会更简单些。