首页 > 解决方案 > 熊猫计算自值>当前单元格以来的行数

问题描述

我有一个数据框df

       col_1
    0  51.0  
    1  52.0  
    2  51.5  
    3  51.5  
    4  53.0  
    5  54.0  
    6  52.0  
    7  53.0  
    8  50.5  
    9  50.0  
   10  52.0  

我想倒数行数,直到找到大于当前值的值,或者直到到达第一行。例如,结果将是:

       col_1 count
    0  51.0  0
    1  52.0  1
    2  51.5  0
    3  51.5  1
    4  53.0  4
    5  54.0  5
    6  52.0  0
    7  53.0  1
    8  50.5  0
    9  50.0  0
   10  52.0  2

我基本上是在尝试为系列的每个值找到nin的值。df['col_1'].rolling(n).max()我怎样才能做到这一点?先感谢您。

标签: pythonpandas

解决方案


Numpy 方法

a = df['col_1'].values[::-1]
m = np.triu(a[:, None] <  a)

i = m.argmax(1)
i[~m.any(1)] = len(m)
df['count'] = (i - range(len(m)) - 1)[::-1]

这个怎么运作?

  • 反转列col_1并获得一个numpy视图
>>> a

array([52. , 50. , 50.5, 53. , 52. , 54. , 53. , 51.5, 51.5, 52. , 51. ])
  • 使用广播比较列a与自身
>>> a[:, None] <  a

[[False False False  True False  True  True False False False False]
 [ True False  True  True  True  True  True  True  True  True  True]
 [ True False False  True  True  True  True  True  True  True  True]
 [False False False False False  True False False False False False]
 [False False False  True False  True  True False False False False]
 [False False False False False False False False False False False]
 [False False False False False  True False False False False False]
 [ True False False  True  True  True  True False False  True False]
 [ True False False  True  True  True  True False False  True False]
 [False False False  True False  True  True False False False False]
 [ True False False  True  True  True  True  True  True  True False]]
  • 使用triu(上三角)掩盖主对角线左侧的值,因为我们只关心当前值之后的值。将此视为代表当前值的主对角线。
>>> np.triu(a[:, None] < a)

[[False False False  True False  True  True False False False False]
 [False False  True  True  True  True  True  True  True  True  True]
 [False False False  True  True  True  True  True  True  True  True]
 [False False False False False  True False False False False False]
 [False False False False False  True  True False False False False]
 [False False False False False False False False False False False]
 [False False False False False False False False False False False]
 [False False False False False False False False False  True False]
 [False False False False False False False False False  True False]
 [False False False False False False False False False False False]
 [False False False False False False False False False False False]]
  • 沿着列轴找到最大值的索引,这表示当前值之后的第一个最大值的索引。如果没有找到最大值,我们将这些索引更新为系列长度
>>> i = m.argmax(1)
>>> i[~m.any(1)] = len(m)
>>> i

array([ 3,  2,  3,  5,  5, 11, 11,  9,  9, 11, 11])
  • 上述索引是从零开始的,但我们必须计算与主对角线的距离,因此我们可以从主对角线的索引中减去这些索引来计算距离(行数)
>>> df['count'] = (i - range(len(m)) - 1)[::-1]
>>> df

    col_1  count
0    51.0      0
1    52.0      1
2    51.5      0
3    51.5      1
4    53.0      4
5    54.0      5
6    52.0      0
7    53.0      1
8    50.5      0
9    50.0      0
10   52.0      2

推荐阅读