python Pandas列值和值列表之间的高效查找

vzgqcmou  于 2022-12-17  发布在  Python
关注(0)|答案(1)|浏览(119)

我有一个包含n个元素的列表,比如:

[5,30,60,180,240]

以及具有以下特征的 Dataframe

id1 id2 feat1
1     1   40
1     2   40
1     3   40
1     4   40
2     6   87
2     7   87
2     8   87

id1 + id2的组合是唯一的,但是具有公共id1的所有记录共享feat1的值。我想编写一个函数,通过groupby + apply运行它(或更快的方法),该方法创建名为“closest_number”的列。对于给定的id1+id2,“closest_number”将是feat1列之间最近的元素(或ID1,因为记录共享Feat1)和列表的每个元素。
预期输出:

id1 id2 feat1 closest_number
1     1   40      30
1     2   40      30
1     3   40      30
1     4   40      30
2     6   87      60
2     7   87      60
2     8   87      60

如果这是一个标准的2数组查找问题,我可以这样做:

def get_closest(array, values):
    # make sure array is a numpy array
    array = np.array(array)

    # get insert positions
    idxs = np.searchsorted(array, values, side="left")
    
    # find indexes where previous index is closer
    prev_idx_is_less = ((idxs == len(array))|(np.fabs(values - array[np.maximum(idxs-1, 0)]) < np.fabs(values - array[np.minimum(idxs, len(array)-1)])))
    idxs[prev_idx_is_less] -= 1
    
    return array[idxs]

如果我应用此命令,则会得到输出列:

array([30, 60])

然而,我不会得到任何关于它们与30和60对应的指数的信息。
什么是最佳的方法呢?由于我的元素列表非常小,我在数据集中创建了距离列,然后我选择了一个能得到最小距离的列。
但我想应该有更优雅的方式来做这件事。
巴西

zf9nrax1

zf9nrax11#

按如下方式使用get_closest

# obtain the series with index id1 and values feat1
vals = df.groupby("id1")["feat1"].first().rename("closest_number")

# find the closest values and assign them back
vals[:] = get_closest(s, vals)

# merge the series into the original DataFrame
res = df.merge(vals, right_index=True, left_on="id1", how="left")

print(res)

产出

id1  id2  feat1  closest_number
0    1    1     40              30
1    1    2     40              30
2    1    3     40              30
3    1    4     40              30
4    2    6     87              60
5    2    7     87              60
6    2    8     87              60

相关问题