Numpy查找与数组匹配的数字

时间:2017-11-08 17:59:39

标签: python arrays numpy

非常感谢任何帮助!!我过去几天一直试图解决这个问题....

我有两个数组:      将pandas导入为pd

 OldDataSet = {
 'id': [20,30,40,50,60,70]
 ,'OdoLength': [26.12,43.12,46.81,56.23,111.07,166.38]}

 NewDataSet = {
 'id': [3000,4000,5000,6000,7000,8000]
 ,'OdoLength': [25.03,42.12,45.74,46,110.05,165.41]}

 df1= pd.DataFrame(OldDataSet)
 df2 = pd.DataFrame(NewDataSet)

 OldDataSetArray = df1.as_matrix()
 NewDataSetArray = df2.as_matrix()

我想要的结果是:

数组1和数组2匹配差异,基于Array2上的左数字

20  26.12   3000    25.03   
30  43.12   4000    42.12   
40  46.81   6000    46  
50  56.23   7000    110.05  
60  111.07  8000    165.41  
70  166.38  0   0   

从数组1,ID 20开始,找到最接近的数组,在这种情况下,它将是数组2 ID 3000(26.12-25.03)中的第一个数字。所以ID 20,匹配到3000。 如果它变得棘手的是,如果数组2中的一个值不是最接近的,则跳过它。例如,ID 40值46.81与45.74,46进行比较,最小值是.81来自46 ID 6000.所以ID 40 - > ID 6000.现在跳过阵列2中的ID 5000以用于任何将来的比较。因此,现在比较阵列1 ID 50时,将其与阵列2中的下一个可用数字110.05进行比较。阵列1 ID 50与阵列2 ID 7000匹配。

更新

所以这里是我尝试过的代码并且有效。是的,它不是最好的,所以如果有人有其他建议,请告诉我。

 import pandas as pd
 import operator 

 OldDataSet = {
 'id': [20,30,40,50,60,70]
 ,'OdoLength': [26.12,43.12,46.81,56.23,111.07,166.38]}

NewDataSet = {
'id': [3000,4000,5000,6000,7000,8000]
,'OdoLength': [25.03,42.12,45.74,46,110.05,165.41]}

df1= pd.DataFrame(OldDataSet)
df2 = pd.DataFrame(NewDataSet)

OldDataSetArray = df1.as_matrix()
NewDataSetArray = df2.as_matrix()




newPos = 1
CurrentNumber = 0
OldArrayLen = len(OldDataSetArray) -1
NewArrayLen = len(NewDataSetArray) -1
numberResults = []

for oldPos in range(len(OldDataSetArray)):
PreviousNumber =  abs(OldDataSetArray[oldPos, 0]- NewDataSetArray[oldPos, 0])


 while newPos <= len(NewDataSetArray) - 1:   
    CurrentNumber = abs(OldDataSetArray[oldPos, 0] - NewDataSetArray[newPos, 0])

#if it is the last row for the inner array, then match the next available 
#in Array 1 to that last record
    if newPos == NewArrayLen and oldPos < newPos and oldPos +1 <= OldArrayLen:
       numberResults.append([OldDataSetArray[oldPos +1, 1],NewDataSetArray[newPos, 1],OldDataSetArray[oldPos +1, 0],NewDataSetArray[newPos, 0]])

    if PreviousNumber < CurrentNumber:
        numberResults.append([OldDataSetArray[oldPos, 1], NewDataSetArray[newPos - 1, 1], OldDataSetArray[oldPos, 0], NewDataSetArray[newPos - 1, 0]])
        newPos +=1
        break
    elif PreviousNumber > CurrentNumber:
        PreviousNumber = CurrentNumber
        newPos +=1  


#sort by array one values        
numberResults = sorted(numberResults, key=operator.itemgetter(0)) 
numberResultsDf = pd.DataFrame(numberResults)

2 个答案:

答案 0 :(得分:2)

您可以使用NumPy广播来构建距离矩阵:

a = numpy.array([26.12, 43.12, 46.81, 56.23, 111.07, 166.38,])
b = numpy.array([25.03, 42.12, 45.74, 46, 110.05, 165.41,])

numpy.abs(a[:, None] - b[None, :])
# array([[   1.09,   16.  ,   19.62,   19.88,   83.93,  139.29],
#        [  18.09,    1.  ,    2.62,    2.88,   66.93,  122.29],
#        [  21.78,    4.69,    1.07,    0.81,   63.24,  118.6 ],
#        [  31.2 ,   14.11,   10.49,   10.23,   53.82,  109.18],
#        [  86.04,   68.95,   65.33,   65.07,    1.02,   54.34],
#        [ 141.35,  124.26,  120.64,  120.38,   56.33,    0.97]])
然后,您可以使用argmin找到最接近的元素,无论是行还是列(取决于您是否要在ab中搜索)。

numpy.argmin(numpy.abs(a[:, None] - b[None, :]), axis=1)
# array([0, 1, 3, 3, 4, 5])

答案 1 :(得分:0)

计算所有差异,并使用`np.argmin查找最接近的。

    a,b=np.random.rand(2,10)

    all_differences=np.abs(np.subtract.outer(a,b))

    ia=all_differences.argmin(axis=1)

    for i in range(10):
        print(i,a[i],ia[i], b[ia[i]])



    0 0.231603891949 8 0.21177584152
    1 0.27810475456 7 0.302647382888
    2 0.582133214953 2 0.548920922033
    3 0.892858042793 1 0.872622982632
    4 0.67293347218 6 0.677971552011
    5 0.985227546492 1 0.872622982632
    6 0.82431697833 5 0.83765895237
    7 0.426992114791 4 0.451084369838
    8 0.181147161752 8 0.21177584152
    9 0.631139744522 3 0.653554586691

修改

包含数据框和索引:

va,vb=np.random.rand(2,10)
na,nb=np.random.randint(0,100,(2,10))

dfa=pd.DataFrame({'id':na,'odo':va})
dfb=pd.DataFrame({'id':nb,'odo':vb})


all_differences=np.abs(np.subtract.outer(dfa.odo,dfb.odo))

ia=all_differences.argmin(axis=1)

dfc=dfa.merge(dfb.loc[ia].reset_index(drop=True),\
left_index=True,right_index=True)

输入:

In [337]: dfa

Out[337]: 
   id       odo
0  72  0.426457
1  12  0.315997
2  96  0.623164
3   9  0.821498
4  72  0.071237
5   5  0.730634
6  45  0.963051
7  14  0.603289
8   5  0.401737
9  63  0.976644

In [338]: dfb
Out[338]: 
   id       odo
0  95  0.333215
1   7  0.023957
2  61  0.021944
3  57  0.660894
4  22  0.666716
5   6  0.234920
6  83  0.642148
7  64  0.509589
8  98  0.660273
9  19  0.658639

输出:

In [339]: dfc
Out[339]: 
   id_x     odo_x  id_y     odo_y
0    72  0.426457    64  0.509589
1    12  0.315997    95  0.333215
2    96  0.623164    83  0.642148
3     9  0.821498    22  0.666716
4    72  0.071237     7  0.023957
5     5  0.730634    22  0.666716
6    45  0.963051    22  0.666716
7    14  0.603289    83  0.642148
8     5  0.401737    95  0.333215
9    63  0.976644    22  0.666716