首页 > 解决方案 > 有效地检查一列中的值是否属于其他两列定义的阈值

问题描述

这个问题的目标是有效地提高我现在将详细说明的问题的执行时间:

我有一个像这样的df:

df

 |   | min  | max   | value |
 |---|------|-------|-------|
 | 0 | 1.0  | 10.0  | 15    |
 | 1 | 50.0 | 100.0 | 20    |
 | 2 | 30.0 | 50.0  | 40    |
 | 3 | 10.0 | 90.0  | 91    |
 | 4 | NaN  | NaN   | 1000  |

我要检查的是 value 列的值是否在 min 和 max 列定义的阈值内。

如果 min 和 max 列等于 Nan,那么我们认为列 value 中的值在阈值内。

为了解决这个问题,我创建了以下代码:

In[1]:
def boundary(row):
    if row['value'] <= row['min'] or row['value'] >= row['max']:
        return 'out of range'
    else:
        return 'ok'
In[2]:
%%timeit
df["boundary"] = df.apply(lambda row: boundary(row), axis=1)
Out[2]:
959 µs ± 21.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

|   | min  | max   | value | boundary     |
| - | ---- | ----- | ----- | ------------ |
| 0 | 1.0  | 10.0  | 15    | out of range |
| 1 | 50.0 | 100.0 | 20    | out of range |
| 2 | 30.0 | 50.0  | 40    | ok           |
| 3 | 10.0 | 90.0  | 91    | out of range |
| 4 | NaN  | NaN   | 1000  | ok           |

我的问题是,有没有更便宜的方法来解决这个问题?

标签: pythonpandas

解决方案


尝试使用:

df['boundary'] = ((df['min'] < df['value']) & (df['value'] < df['max'])) | (df['min'].isna() | df['max'].isna())

时间:

771 µs ± 5.82 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

事实:

df["boundary"] = df.apply(lambda row: boundary(row), axis=1)
999 µs ± 11.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

您不需要循环也不需要在这里应用,因为 pandas 会自动排列索引上的数据以进行比较,并将进行矢量化处理。


推荐阅读