in1d
和setdiff1d
等许多功能都是针对一维数组设计的。在N维数组上应用这些方法的一种解决方法是使numpy
将每行(更高维度的东西)视为值。
我发现这样做的一种方法是在Joe Kington的回答中Get intersecting rows across two 2D numpy arrays。
以下代码取自此答案。 Joe Kington面临的任务是在尝试使用A
时检测两个数组B
和in1d
中的常见行。
import numpy as np
A = np.array([[1,4],[2,5],[3,6]])
B = np.array([[1,4],[3,6],[7,8]])
nrows, ncols = A.shape
dtype={'names':['f{}'.format(i) for i in range(ncols)],
'formats':ncols * [A.dtype]}
C = np.intersect1d(A.view(dtype), B.view(dtype))
# This last bit is optional if you're okay with "C" being a structured array...
C = C.view(A.dtype).reshape(-1, ncols)
我希望您能帮助我解决以下三个问题。首先,我不明白这种方法背后的机制。你能试着向我解释一下吗?
第二,还有其他方法让numpy将子阵列视为一个对象吗?
另一个悬而未决的问题:乔的方法有什么缺点?我的意思是将行作为值处理可能会导致一些问题吗?对不起,这个问题非常广泛。
答案 0 :(得分:0)
尝试发布我学到的东西。 Joe使用的方法称为structured arrays。它将允许用户定义单个单元格/元素中包含的内容。
我们来看一下文档提供的第一个例子的描述。
x = np.array([(1,2.,'Hello'), (2,3.,"World")], ... dtype=[('foo', 'i4'),('bar', 'f4'), ('baz', 'S10')])
这里我们创建了一个一维 长度为2 的数组。 每个元素 这个数组是一个结构,包含三个项,一个32位 整数,32位浮点数和长度为10或更小的字符串。
但是,如果没有传入dtype
,我们将得到一个2乘3的矩阵。
使用这种方法,我们可以让numpy
将更高维数组作为单个元素处理,并正确设置dtype
。
Joe表示的另一个技巧是我们不需要真正形成一个新的numpy数组来实现这个目的。我们可以使用view
函数(请参阅ndarray.view
)更改numpy
查看数据的方式。在ndarray.view
中有一段Note
部分我认为您应该在使用该方法之前先查看一下。 我无法保证不存在副作用。以下段落来自注释部分,似乎要求谨慎。
对于a.view(some_dtype),如果some_dtype每个条目的字节数与前一个dtype不同(例如,将常规数组转换为结构化数组),则只能从a的表面外观(由print(a)显示)来预测视图的行为。它还取决于a如何存储在内存中。因此,如果a是C序列与fortran-ordered,而不是定义为切片或转置等,则视图可能会给出不同的结果。
其他参考
https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.dtypes.html https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.dtype.html