python将索引升序_python – 将数组排序到索引数组指定的bin中...

这篇博客介绍了多种在Python中将数据根据索引排序并分配到指定bin的方法,包括使用`np.argsort`、`np.bincount`、`np.argpartition`、`scipy.ndimage.measurements.labeled_comprehension`、Pandas和Scipy.sparse等。文章通过基准测试比较了这些方法的性能,并提供了代码示例。
摘要由CSDN通过智能技术生成

以下是一些解决方案:

>无论如何,使用np.argsort,毕竟它是快速编译的代码.

>使用np.bincount获取bin大小和np.argpartition,它是固定数量的bin的O(n).缺点:目前,没有稳定的算法可用,因此我们必须对每个bin进行排序.

>使用scipy.ndimage.measurements.labeled_comprehension.这大致是需要的,但不知道它是如何实现的.

>使用熊猫.我是一个完整的大熊猫菜鸟,所以我在这里用groupby拼凑在一起可能不是最理想的.

>使用压缩稀疏行和压缩稀疏列格式之间的scipy.sparse切换实现我们正在寻找的确切操作.

>在问题中的循环代码中使用pythran(我确定numba也能正常工作).所有需要的是在numpy导入后插入顶部

.

#pythran export sort_to_bins(int[:], float[:], int)

然后编译

# pythran stb_pthr.py

基准100箱,可变数量的物品:

带回家:

如果你对numba / pythran没问题就可以了,如果不是scipy.sparse可以很好地扩展.

码:

import numpy as np

from scipy import sparse

from scipy.ndimage.measurements import labeled_comprehension

from stb_pthr import sort_to_bins as sort_to_bins_pythran

import pandas as pd

def sort_to_bins_pandas(idx, data, mx=-1):

df = pd.DataFrame.from_dict(data=data)

out = np.empty_like(data)

j = 0

for grp in df.groupby(idx).groups.values():

out[j:j+len(grp)] = data[np.sort(grp)]

j += len(grp)

return out

def sort_to_bins_ndimage(idx, data, mx=-1):

if mx==-1:

mx = idx.max() + 1

out = np.empty_like(data)

j = 0

def collect(bin):

nonlocal j

out[j:j+len(bin)] = np.sort(bin)

j += len(bin)

return 0

labeled_comprehension(data, idx, np.arange(mx), collect, data.dtype, None)

return out

def sort_to_bins_partition(idx, data, mx=-1):

if mx==-1:

mx = idx.max() + 1

return data[np.argpartition(idx, np.bincount(idx, None, mx)[:-1].cumsum())]

def sort_to_bins_partition_stable(idx, data, mx=-1):

if mx==-1:

mx = idx.max() + 1

split = np.bincount(idx, None, mx)[:-1].cumsum()

srt = np.argpartition(idx, split)

for bin in np.split(srt, split):

bin.sort()

return data[srt]

def sort_to_bins_sparse(idx, data, mx=-1):

if mx==-1:

mx = idx.max() + 1

return sparse.csr_matrix((data, idx, np.arange(len(idx)+1)), (len(idx), mx)).tocsc().data

def sort_to_bins_argsort(idx, data, mx=-1):

return data[idx.argsort(kind='stable')]

from timeit import timeit

exmpls = [np.random.randint(0, K, (N,)) for K, N in np.c_[np.full(16, 100), 1<

timings = {}

for idx in exmpls:

data = np.arange(len(idx), dtype=float)

ref = None

for x, f in (*globals().items(),):

if x.startswith('sort_to_bins_'):

timings.setdefault(x.replace('sort_to_bins_', '').replace('_', ' '), []).append(timeit('f(idx, data, -1)', globals={'f':f, 'idx':idx, 'data':data}, number=10)*100)

if x=='sort_to_bins_partition':

continue

if ref is None:

ref = f(idx, data, -1)

else:

assert np.all(f(idx, data, -1)==ref)

import pylab

for k, v in timings.items():

pylab.loglog(1<

pylab.xlabel('#items')

pylab.ylabel('time [ms]')

pylab.legend()

pylab.show()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值