首先,您可以使用data.reshape(N,-1),因为您有兴趣对最后两个维度进行排序。
获取每行唯一值数量的简单方法是将每行转储到一个集合中并让它进行排序:
[len(set(i)) for i in data.reshape(data.shape[0],-1)]
但这是一个迭代,可能是一个快速的迭代。
“向量化”的一个问题是每行中唯一值的集合或列表的长度会有所不同。当涉及到“矢量化”时,“不同长度的行”是一个危险信号。您不再拥有使大多数矢量化成为可能的“矩形”数据布局。
您可以对每一行进行排序:
np.sort(data.reshape(N,-1))
array([[1, 2, 2, 3, 3, 5, 5, 5, 6, 6],
[1, 1, 1, 2, 2, 2, 3, 3, 5, 7],
[0, 0, 2, 3, 4, 4, 4, 5, 5, 9],
[2, 2, 3, 3, 4, 4, 5, 7, 8, 9],
[0, 2, 2, 2, 2, 5, 5, 5, 7, 9]])
但是如何在不迭代的情况下识别每一行中的唯一值?计算非零差异的数量可能就可以解决问题:
In [530]: data=np.random.randint(10,size=(5,10))
In [531]: [len(set(i)) for i in data.reshape(data.shape[0],-1)]
Out[531]: [7, 6, 6, 8, 6]
In [532]: sdata=np.sort(data,axis=1)
In [533]: (np.diff(sdata)>0).sum(axis=1)+1
Out[533]: array([7, 6, 6, 8, 6])
我打算添加一个关于浮点数的警告,但如果 np.unique 对您的数据有效,那么我的方法应该同样有效。
[(np.bincount(i)>0).sum() for i in data]
这是一个迭代解决方案,明显比我的len(set(i)) 版本更快,并且与diff...sort 相比具有竞争力。
在 [585] 中:data.shape
输出[585]: (10000, 400)
In [586]: timeit [(np.bincount(i)>0).sum() for i in data]
1 loops, best of 3: 248 ms per loop
In [587]: %%timeit
sdata=np.sort(data,axis=1)
(np.diff(sdata)>0).sum(axis=1)+1
.....:
1 loops, best of 3: 280 ms per loop
我刚刚找到了一种更快的方法来使用bincount、np.count_nonzero
In [715]: timeit np.array([np.count_nonzero(np.bincount(i)) for i in data])
10 loops, best of 3: 59.6 ms per loop
我对速度的提高感到惊讶。但后来我想起count_nonzero 用于其他函数(例如np.nonzero)来为其返回结果分配空间。因此,将此函数编码为最大速度是有道理的。 (它在diff...sort 的情况下没有帮助,因为它不采用轴参数)。