使用排序列更有效地获取数据框中最小元素的整体分布



我有一个带有排序列的数据帧,类似于以下内容:

df = pd.DataFrame({q: np.sort(np.random.randn(10).round(2)) for q in ['blue', 'green', 'red']})
blue  green   red
0 -2.15  -0.76 -2.62
1 -0.88  -0.62 -1.65
2 -0.77  -0.55 -1.51
3 -0.73  -0.17 -1.14
4 -0.06  -0.16 -0.75
5 -0.03   0.05 -0.08
6  0.06   0.38  0.37
7  0.41   0.76  1.04
8  0.56   0.89  1.16
9  0.97   2.94  1.79

我想知道的是,整个框架中有多少n最小元素在每列中。这是我唯一想到的东西:

is_small = df.isin(np.partition(df.values.flatten(), n)[:n])

当n=10时,它看起来像这样:

blue  green    red
0   True   True   True
1   True  False   True
2   True  False   True
3   True  False   True
4  False  False   True
5  False  False  False
6  False  False  False
7  False  False  False
8  False  False  False
9  False  False  False

然后通过应用np.sum,我得到了对应于每一列的数字。

我对这个解决方案不满意,因为它根本没有利用原始数据的排序性All对数据进行分区,然后检查数据是否在分区中。这似乎很浪费,我似乎想不出更好的办法了。

认为您可以将n个最小值中的最大值与分区值进行比较,然后使用idxmin来利用排序特性-

# Find largest of n smallest numbers
N = (np.partition(df.values.flatten(), n)[:n]).max()
out = (df<=N).idxmin(axis=0)

样品运行-

In [152]: np.random.seed(0)
In [153]: df = pd.DataFrame({q: np.sort(np.random.randn(10).round(2)) 
for q in ['blue', 'green', 'red']})
In [154]: df
Out[154]: 
blue  green   red
0 -0.98  -0.85 -2.55
1 -0.15  -0.21 -1.45
2 -0.10   0.12 -0.74
3  0.40   0.14 -0.19
4  0.41   0.31  0.05
5  0.95   0.33  0.65
6  0.98   0.44  0.86
7  1.76   0.76  1.47
8  1.87   1.45  1.53
9  2.24   1.49  2.27
In [198]: n = 5
In [199]: N = (np.partition(df.values.flatten(), n)[:n]).max()
In [200]: (df<=N).idxmin(axis=0)
Out[200]: 
blue     1
green    1
red      3
dtype: int64

比方说,你正在寻找10个最小的,你可以堆叠并找到10个最小的value_count

df.stack().nsmallest(10).index.get_level_values(1).value_counts()

你得到

red      5
blue     4
green    1

最新更新