如何在Pandas系列中找到与输入数字最接近的值?

问题描述 投票:28回答:5

我见过:

这些与香草蟒蛇有关,而不是熊猫。

如果我有这个系列:

ix   num  
0    1
1    6
2    4
3    5
4    2

我输入3,我怎样才能(有效地)找到?

  1. 如果在系列中找到,则索引为3
  2. 如果在系列中找不到,则该值的索引低于和高于3。

IE浏览器。使用上面的系列{1,6,4,5,2}和输入3,我应该得到带有索引(2,4)的值(4,2)。

python pandas dataframe ranking
5个回答
30
投票

你可以使用像argsort()

说,input = 3

In [198]: input = 3

In [199]: df.ix[(df['num']-input).abs().argsort()[:2]]
Out[199]:
   num
2    4
4    2

df_sort是具有2个最接近值的数据帧。

In [200]: df_sort = df.ix[(df['num']-input).abs().argsort()[:2]]

对于索引,

In [201]: df_sort.index.tolist()
Out[201]: [2, 4]

对于价值观,

In [202]: df_sort['num'].tolist()
Out[202]: [4, 2]

细节,对于上述解决方案df

In [197]: df
Out[197]:
   num
0    1
1    6
2    4
3    5
4    2

15
投票

我推荐使用iloc以及John Galt的答案,因为即使使用未排序的整数索引也可以使用.ix,因为df.iloc[(df['num']-input).abs().argsort()[:2]] 首先查看索引标签

def find_neighbours(value):
    exactmatch=df[df.num==value]
        if !exactmatch.empty:
            return exactmatch.index[0]
        else:
            lowerneighbour_ind = df[df.num<value].idxmax()
            upperneighbour_ind = df[df.num>traversed].idxmin()
            return lowerneighbour_ind, upperneighbour_ind

4
投票

这里讨论的其他算法的缺点是它们必须对整个列表进行排序。这导致~N log(N)的复杂性。

但是,可以在~N中获得相同的结果。这种方法将数据帧分成两个子集,一个小于一个子集,一个大于期望值。较低的邻居比较小的数据帧中的最大值,反之亦然。

这给出了以下代码片段:

partition in pandas

这种方法类似于使用def closest(df, col, val, direction): n = len(df[df[col] <= val]) if(direction < 0): n -= 1 if(n < 0 or n >= len(df)): print('err - value outside range') return None return df.ix[n, col] df = pd.DataFrame(pd.Series(range(0,10,2)), columns=['num']) for find in range(-1, 2): lc = closest(df, 'num', find, -1) hc = closest(df, 'num', find, 1) print('Closest to {} is {}, lower and {}, higher.'.format(find, lc, hc)) df: num 0 0 1 2 2 4 3 6 4 8 err - value outside range Closest to -1 is None, lower and 0, higher. Closest to 0 is 0, lower and 2, higher. Closest to 1 is 0, lower and 2, higher. ,这在处理大型数据集时非常有用,并且复杂性成为一个问题。


2
投票

如果你的系列已经排序,你可以使用这样的东西。

bisect

1
投票

如果系列已经排序,找到索引的有效方法是使用idx = bisect_right(df['num'].values, 3) 。一个例子:

from bisect import bisect_right, bisect_left
def get_closests(df, col, val):
    lower_idx = bisect_right(df[col].values, val)
    higher_idx = bisect_left(df[col].values, val)
if higher_idx == lower_idx:
    return lower_idx
else: 
    return lower_idx, higher_idx

因此,对于问题中引用的问题,考虑到数据框“df”的列“col”已排序:

qazxswpoi

在数据帧列“col”或其最近邻居中找到特定值“val”的索引非常有效,但它需要对列表进行排序。

© www.soinside.com 2019 - 2024. All rights reserved.