基本的 Numpy 和 Pandas 解决方案
没有完全预打包的方法(在 Numpy 中),但有很多单行。以下是使用比较和逻辑操作的方法(编辑向 Paul Panzer 致敬,建议使用 np.count_nonzero):
import numpy as np
arr = np.linspace(-15,15,1000)
np.count_nonzero((arr > -10) & (arr < 10))/arr.size
输出:
0.666
如果您愿意使用 Pandas,pandas.Series.between method 可以让您更接近您想要的完整软件包:
import pandas as pd
sr = pd.Series(np.linspace(-15,15,1000))
np.count_nonzero(sr.between(-10,10))/sr.size
输出:
0.666
陷阱
每种区间分析方法都涉及您正在考虑的区间的显式或隐式定义。区间是否在两端闭合(即包括极值),如[-10, 10]?还是半开(即排除一端的极值),如[-10, 10)?以此类推。
在处理从数据中获取的 float 值数组时,这往往不是问题(因为任何数据都不太可能完全处于极端),但在处理 int 数组时可能会导致严重问题.例如,如果数组包含区间的边界值,我上面列出的两种方法会给出不同的结果:
arr = np.arange(-15,16)
print(np.count_nonzero((arr > -10) & (arr < 10))/arr.size)
print(np.count_nonzero(pd.Series(arr).between(-10,10))/arr.size)
输出:
0.6129032258064516
0.6774193548387096
pd.Series.between 方法默认为两端的闭区间,因此要在 Numpy 中匹配它,您必须使用包含比较运算符:
arr = np.arange(-15,16)
print(np.count_nonzero((arr >= -10) & (arr <= 10))/arr.size)
print(np.count_nonzero(pd.Series(arr).between(-10,10))/arr.size)
输出:
0.6774193548387096
0.6774193548387096
所有这些都是说:当您为这种区间分析选择一种方法时,请注意它的边界约定,并在所有相关分析中使用一致的约定。
其他解决方案
如果您假设数据已排序(或者如果您自己排序),则可以使用np.searchsorted:
arr = np.random.uniform(-15,15,100)
arr.sort()
np.diff(arr.searchsorted([-10, 10]))[0]/arr.size
输出:
0.65