Python/Pandas 在一列中找到最接近的值 above/below
Python/Pandas find closest value above/below in one Column
我有一个大数据框(约 100 万行)。我最终将在两个年龄组之间插入光谱。但是,我需要首先找到高于和低于我需要找到的任何年龄的最接近值。
DataFrame 大致如下所示
Age Wavelength Luminosity
1
1
1
4
4
6
6
我需要能够输入 5,return 值 4 和 6。我正在努力寻找一种方法来做到这一点?这是我试过的:
def findnearest(array,value):
idx = np.searchsorted(array,value, side='left')
if idx > 125893.0:
return array[idx]
else:
return array[idx]
idx1 = np.searchsorted(array,value, side='right')
if idx1 < 2e10:
return array[idx1]
else:
return array [idx1-1]
C = findnearest(m05_010['age'], 5.12e7)
print(C)
这只是 return 一个值,而不是两个。这是正确的道路还是我应该做些不同的事情?有没有更好的方法?
IIUC 并假设输入数组已排序,您可以这样做 -
above = arr[np.searchsorted(arr,value,'left')-1]
below = arr[np.searchsorted(arr,value,'right')]
样品运行 -
情况 1:值没有完全匹配
In [17]: arr = np.array([1,1,1,4,4,4,4,4,4,4,6,6])
In [18]: value = 5
In [19]: above = arr[np.searchsorted(arr,value,'left')-1]
...: below = arr[np.searchsorted(arr,value,'right')]
...:
In [20]: above, below
Out[20]: (4, 6)
情况 2:值完全匹配
In [33]: arr = np.array([1,1,1,4,4,4,4,4,4,4,5,5,5,6,6])
In [34]: value = 5
In [35]: above = arr[np.searchsorted(arr,value,'left')-1]
...: below = arr[np.searchsorted(arr,value,'right')]
...:
In [36]: above, below
Out[36]: (4, 6)
我认为你应该使用 bisect
,它的速度要快得多,而且专为此目的而设计。
from bisect import *
arr = np.array([1,1,1,4,4,4,4,4,4,4,6,6])
value = 5
lower = arr[bisect_left(arr, value) - 1]
above = arr[bisect_right(arr, value)]
lower, above
输出 -
(4, 6)
这是 Ipython -
的时间比较
%timeit for x in range(100): arr[bisect_left(arr, value)]
输出 -
10000 loops, best of 3: 92.4 µs per loop
并使用 searchsorted
-
%timeit for x in range(100): arr[np.searchsorted(arr,value,'left')-1]
输出 -
The slowest run took 7.62 times longer than the fastest. This could
mean that an intermediate result is being cached. 10000 loops, best of
3: 142 µs per loop
我有一个大数据框(约 100 万行)。我最终将在两个年龄组之间插入光谱。但是,我需要首先找到高于和低于我需要找到的任何年龄的最接近值。
DataFrame 大致如下所示
Age Wavelength Luminosity
1
1
1
4
4
6
6
我需要能够输入 5,return 值 4 和 6。我正在努力寻找一种方法来做到这一点?这是我试过的:
def findnearest(array,value):
idx = np.searchsorted(array,value, side='left')
if idx > 125893.0:
return array[idx]
else:
return array[idx]
idx1 = np.searchsorted(array,value, side='right')
if idx1 < 2e10:
return array[idx1]
else:
return array [idx1-1]
C = findnearest(m05_010['age'], 5.12e7)
print(C)
这只是 return 一个值,而不是两个。这是正确的道路还是我应该做些不同的事情?有没有更好的方法?
IIUC 并假设输入数组已排序,您可以这样做 -
above = arr[np.searchsorted(arr,value,'left')-1]
below = arr[np.searchsorted(arr,value,'right')]
样品运行 -
情况 1:值没有完全匹配
In [17]: arr = np.array([1,1,1,4,4,4,4,4,4,4,6,6])
In [18]: value = 5
In [19]: above = arr[np.searchsorted(arr,value,'left')-1]
...: below = arr[np.searchsorted(arr,value,'right')]
...:
In [20]: above, below
Out[20]: (4, 6)
情况 2:值完全匹配
In [33]: arr = np.array([1,1,1,4,4,4,4,4,4,4,5,5,5,6,6])
In [34]: value = 5
In [35]: above = arr[np.searchsorted(arr,value,'left')-1]
...: below = arr[np.searchsorted(arr,value,'right')]
...:
In [36]: above, below
Out[36]: (4, 6)
我认为你应该使用 bisect
,它的速度要快得多,而且专为此目的而设计。
from bisect import *
arr = np.array([1,1,1,4,4,4,4,4,4,4,6,6])
value = 5
lower = arr[bisect_left(arr, value) - 1]
above = arr[bisect_right(arr, value)]
lower, above
输出 -
(4, 6)
这是 Ipython -
的时间比较%timeit for x in range(100): arr[bisect_left(arr, value)]
输出 -
10000 loops, best of 3: 92.4 µs per loop
并使用 searchsorted
-
%timeit for x in range(100): arr[np.searchsorted(arr,value,'left')-1]
输出 -
The slowest run took 7.62 times longer than the fastest. This could
mean that an intermediate result is being cached. 10000 loops, best of 3: 142 µs per loop