让两个ndarray:形状为A
的{{1}}和形状为(n, *m)
的{{1}}。有没有一种方法可以使用对B
进行排序的顺序来对(n, )
进行就地排序?
使用np.argsort
很容易将A
与B
进行排序,但这不是就地完成的:
A
评论:
B
和A = A[np.argsort(B)]
具有不同的dtype,而A
可以具有多个二维。因此,无法将它们堆叠在一起以使用B
。A
占用了大量空间,这就是为什么需要对其进行就地排序的原因。因此,任何需要ndarray.sort()
占用两倍空间的解决方案都将无法达到这个目的。答案 0 :(得分:1)
如果您可以预先将 private void LoadLineChart()
{
seriesCollection = new SeriesCollection
{
new ColumnSeries
{
Title = "1988",
Values = new ChartValues<double> { 10, 50, 39, 50, 5, 10, 15, 20, 25, 30, 35, 40, 9, 18, 27, 36, 2, 4, 6, 8, 10, 12, 14,
16, 3, 6, 9, 12, 14, 17, 21 }
}
};
//adding series will update and animate the chart automatically
seriesCollection.Add(new ColumnSeries
{
Title = "1989",
Values = new ChartValues<double> { 12, 71, 41, 21, 9, 6, 3, 61, 41, 21, 01, 8, 6, 4, 2, 63, 72, 81, 9, 04, 53, 03, 52, 02,
51, 01, 5, 05, 93, 05, 01 }
});
**LineChart.Series = seriesCollection;**
}
设置为结构化数组,其数据类型由形状为A
的子数组和相同类型的标量(例如{{ 1}}),则可以相对于(m, )
对它进行就地排序。例如:
np.int32
答案 1 :(得分:1)
这是一个解决方案,可以通过遵循索引数组中的循环来工作。可以选择使用pythran对其进行编译,如果行较小(10个元素为80x),则可以大大提高速度;如果行较大(1000个元素为30%),则可以提供较小的速度。
要使其与pythran兼容,我必须对其进行一些简化,因此它仅接受2D数组,并且仅沿轴0排序。
代码:
import numpy as np
#pythran export take_inplace(float[:, :] or int[:, :], int[:])
def take_inplace(a, idx):
n, m = a.shape
been_there = np.zeros(n, bool)
keep = np.empty(m, a.dtype)
for i in range(n):
if been_there[i]:
continue
keep[:] = a[i]
been_there[i] = True
j = i
k = idx[i]
while not been_there[k]:
a[j] = a[k]
been_there[k] = True
j = k
k = idx[k]
a[j] = keep
使用编译版本运行样本。如上所示,仅对于较小的行才需要编译,对于较大的行,纯python应该足够快。
>>> from timeit import timeit
>>> import numpy as np
>>> import take_inplace
>>>
>>> a = np.random.random((1000, 10))
>>> idx = a[:, 4].argsort()
>>>
>>> take_inplace.take_inplace(a, idx)
>>>
# correct
>>> np.all(np.arange(1000) == a[:, 4].argsort())
True
>>>
# speed
>>> timeit(lambda: take_inplace.take_inplace(a, idx), number=1000)
0.011950935004279017
>>>
# for comparison
>>> timeit(lambda: a[idx], number=1000)
0.02985276997787878