快速的问题
我希望能够比较两个保证具有相同 dtype 的 numpy 结构化数组中的特定 dtype 字段。我想这样做的方式是,每次根据给定的输入调用函数时,我们正在比较的字段都是不同的(即,我不能轻易地对每个单独字段的比较进行硬编码)
示例的长期问题
我正在尝试比较两个具有相同 dtype 的 numpy 结构化数组中的特定字段。例如,假设我们有
import numpy as np
from io import BytesIO
a = np.genfromtxt(BytesIO('12 23 0|23.2|17.9|0\n12 23 1|13.4|16.9|0'.encode()),dtype=[('id','U7'),('pos',[('x',float),('y',float)]),('flag','U1')],delimiter='|')
b = np.genfromtxt(BytesIO(' |23.0|17.91|0'.encode()),dtype=[('id','U7'),('pos',[('x',float),('y',float)]),('flag','U1')],delimiter='|')
这使
In[156]: a
Out[154]:
array([('12 23 0', (23.2, 17.9), '0'), ('12 23 1', (13.4, 16.9), '0')],
dtype=[('id', '<U7'), ('pos', [('x', '<f8'), ('y', '<f8')]), ('flag', '<U1')])
和
In[153]: b
Out[151]:
array([('', (23.0, 17.91), '0')],
dtype=[('id', '<U7'), ('pos', [('x', '<f8'), ('y', '<f8')]), ('flag', '<U1')])
现在假设我想检查并查找a
其a['pos']['x']
字段大于该b['pos']['x']
字段的任何条目并将这些条目返回到一个新的 numpy 数组,这样的事情会起作用
newArr = a[a["pos"]["x"]>b["pos"]["x"]]
现在想象一下,我们只想保留和字段a
都大于. 这很简单,因为我们可以再次这样做x
y
b
newArr = a[np.array([np.array([a['pos']['x']>b['pos']['x']),a['pos']['y']>b['pos']['y'])).all(axis=0)]
它返回一个空数组,这是正确的答案。
然而,现在假设我们有一个非常复杂的 dtype 用于这些数组(比如有 34 个字段 - 请参阅此处以获取我正在使用的 dtype 的示例)并且我们希望能够比较它们中的任何一个,但可能不是全部其中(类似于前面的示例,但总体上有更多的 dtype 字段,并且我们想要比较更多的字段。此外,如果我们要比较的字段可以从运行到运行(所以我们不能真正硬编码)我上面做的方式)。这就是我试图找到解决方案的问题。
我目前(未完成)的解决方案尝试
使用掩码数组
我解决这个问题的第一个想法是使用掩码数组来选择我们想要比较的数据类型字段。像这样(假设我们可以使所有的比较相同):
mask = np.ones(z.shape,dtype=[('id',bool),('pos',[('x',bool),('y',bool)]),('flag',bool)])
# unmask the x and y fields so we can compare them
mask['pos']['x']=0
mask['pos']['y']=0
maskedA = np.ma.masked_array(a, mask=mask)
# We need to do this or the masked array gets angry (at least in python 3)
b.shape = (1,)
maskedB = np.ma.masked_array(b, mask=mask)
现在我想做类似的事情
test = (maskedA>maskedB).any(axis=1)
但这不起作用,因为您可以像这样比较结构化数组-
TypeError: unorderable types: MaskedArray() > MaskedArray()
我也尝试过压缩掩码数组
test = (maskedA.compressed()>maskedB.compressed()).any(axis=1)
这会导致不同的错误
TypeError: ufunc 'logical_not' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
现在,我意识到上述错误很可能是因为我不完全了解结构化和屏蔽数组的工作原理,但这也是我问这个问题的部分原因。有没有办法使用屏蔽数组来做这样的事情?
我刚刚想到的解决方案可能会起作用,并且总体上可能会更好......
所以我在写这篇文章时想到的另一个选择是在我将解析用户的输入以形成数组时进行比较b
。它实际上只是向解析器中的每个条件添加几行来进行比较并将结果添加到一个 numpy 布尔数组中,然后我可以使用该数组从中提取正确的条目a
。现在我想这可能是要走的路。
我漫长而漫无边际的问题的结论。
尽管我认为我找到了解决这个问题的方法,但我仍然会至少发布这个问题,看看(a)是否有人对如何与结构化/屏蔽的 numpy 数组进行逻辑比较有任何想法,因为我认为了解和(b)看看是否有人比我想出的想法更好。请注意,您可以通过逐行复制“示例的长问题”部分中的片段来非常轻松地形成 MWE,我认为这样做没有任何理由占用更多空间。