Python 根据其关联ID在“主顺序”数组中的位置对numpy数组重新排序

Python 根据其关联ID在“主顺序”数组中的位置对numpy数组重新排序,python,numpy,Python,Numpy,我正在寻找一个函数,当数组长度为一百万时,该函数根据有序的_id生成一个新的值数组 输入: >>> ids=array(["WYOMING01","TEXAS01","TEXAS02",...]) >>> values=array([12,20,30,...]) >>> ordered_ids=array(["TEXAS01","TEXAS02","ALABAMA01",...]) ordered [ 20

我正在寻找一个函数,当数组长度为一百万时,该函数根据有序的_id生成一个新的值数组

输入:

    >>> ids=array(["WYOMING01","TEXAS01","TEXAS02",...])
    >>> values=array([12,20,30,...])
    >>> ordered_ids=array(["TEXAS01","TEXAS02","ALABAMA01",...])
    ordered [  20 , 30 , nan , ...]
输出:

    >>> ids=array(["WYOMING01","TEXAS01","TEXAS02",...])
    >>> values=array([12,20,30,...])
    >>> ordered_ids=array(["TEXAS01","TEXAS02","ALABAMA01",...])
    ordered [  20 , 30 , nan , ...]
期末总结

@Dietrich在列表理解中使用字典的速度是使用numpy索引搜索(numpy.where)的10倍。我在下面的回答中比较了三个结果的次数

您可以尝试:

import numpy as np

def order_array(ids, values, master_order_ids):
    n = len(master_order_ids)
    idx = np.searchsorted(master_order_ids, ids)
    ordered_values = np.zeros(n)
    ordered_values[idx < n] = values[idx < n]
    print "ordered", ordered_values
    return ordered_values
将numpy导入为np
def订单数组(ID、值、主订单ID):
n=长度(主订单ID)
idx=np.searchsorted(主订单ID,ID)
有序_值=np.零(n)
有序_值[idx

Searchsorted为您提供了索引,您应该在其中将ID插入主\u order\u ID以保持阵列的有序性。然后,您只需删除那些超出主订单ID范围的(idx,值)。

您可以尝试使用
dict()
将stings与您的号码关联起来。它大大简化了代码:

import numpy as np

def order_bydict(ids,values,master_order_ids):
    """ Using a dict to order ``master_order_ids`` """

    dd = dict([(k,v) for k,v in zip(ids, values)])  # create the dict
    ordered_values = [dd.get(m, 0) for m in master_order_ids]  # get() return 0 if key not found

    return np.asarray(ordered_values)  # return a numpy array instead of a list
如果不测试较长的阵列,很难预测速度方面的改进(在您的示例中,基于
%timeit
,速度提高了25%)

结果
以下使用该软件包的解决方案(免责声明:我是其作者)是纯矢量化的,可能比目前发布的解决方案效率更高:

import numpy_indexed as npi
idx = npi.indices(ids, ordered_ids, missing='mask')
new_values = values[idx]
new_values[idx.mask] = -1   # or cast to float and set to nan, but you get the idea...

[“8”、“9”、“10”]
未按字符串排序,因此它会自动返回虚假结果。对。我默默地希望ID作为字符串是一个错误。我的错。作为对Jamie评论的回应,你能澄清一下你的ID是字符串吗?它们必须是字符串吗?您的master_id数组是否等同于np.arange(n)up类型,或者它是否缺少值?为什么要使用numpy数组?为什么不是一个简单的字符串列表呢?在您的示例中,master_order_id似乎是一个排序列表。如果总是这样,你就不需要它,你的问题也会简单得多。你可能会对这个问题感兴趣:谢谢。我对数组中10000个元素的测试(见下面的答案)表明,您的方法要好得多:不使用dictionary:1.32,使用dictionary:1.32,使用dictionary:0.013