python pandas获取比当前行值大的数据?

values = [[5.5, 2.5, 10.0], [2.0, 4.5, 1.0], [2.5, 5.2, 8.0],[4.5, 5.8, 4.8], [4.6, 6.3, 9.6],[4.1, 6.4, 9.0],[5.1, 2.3, 3],[5.1, 2.3, 11.1],[5.1, 2.3, 10],[5.1, 2.3, 11.1],[5.1, 2.3, 20],[5.1, 2.3, 31],[5.1, 2.3, 5]]
df = pd.DataFrame(values, columns=['col1', 'col2', 'col3'])

输出

    col1  col2  col3
0    5.5   2.5  10.0
1    2.0   4.5   1.0
2    2.5   5.2   8.0
3    4.5   5.8   4.8
4    4.6   6.3   9.6
5    4.1   6.4   9.0
6    5.1   2.3   3.0
7    5.1   2.3  11.1
8    5.1   2.3  10.0
9    5.1   2.3  11.1
10   5.1   2.3  20.0
11   5.1   2.3  31.0
12   5.1   2.3   5.0

我现在需要 增加一个新列 col4

条件是 从当前col3对应的当前行值 向上寻找第一次比当前值大的值到当前值之间的个数作为新增列的对应的行值

最终需要的数据是

    col1  col2  col3   col4
0    5.5   2.5  10.0    0
1    2.0   4.5   1.0     0
2    2.5   5.2   8.0     1
3    4.5   5.8   4.8      0
4    4.6   6.3   9.6      3
5    4.1   6.4   9.0      0
6    5.1   2.3   3.0      0
7    5.1   2.3  11.1      7
8    5.1   2.3  10.0      0
9    5.1   2.3  11.1      1
10   5.1   2.3  20.0      10
11   5.1   2.3  31.0       11
12   5.1   2.3   5.0       0

我知道把col3的值放数组里面,用for逆向循环可以轻松实现这个需求,但是请问 怎么用pandas写高效的代码,来实现这个功能;

阅读 2.5k
3 个回答

给你一个更加简单高效的方式,在大量数据的情况下,利用矩阵计算,避免查找循环,能够让时间复杂度降到o(1)。

count_larger = lambda x: np.sum(x > x[-1])
df['col4'] = [count_larger(df[:i + 1]['col3'].values) for i in range(len(df))]
def main_add(_a, _b):
    for i in range(len(_b[0]) - 1, -1, -1):
        if _b[0][i] < _a:
            _b[1] = _b[1] + 1
        else:
            break
    _c = _b[1]
    _b[0].append(_a)
    _b[1] = 0
    return _c

定义一个函数

a = [[], 0]
df['col4'] = df['col3']
df['col4'] = df[['col3', ]].apply(lambda x: main_add(x['col3'], a), axis=1)

这样可以实现上面的需求

输出、

    col1  col2  col3  col4
0    5.5   2.5  10.0     0
1    2.0   4.5   1.0     0
2    2.5   5.2   8.0     1
3    4.5   5.8   4.8     0
4    4.6   6.3   9.6     3
5    4.1   6.4   9.0     0
6    5.1   2.3   3.0     0
7    5.1   2.3  11.1     7
8    5.1   2.3  10.0     0
9    5.1   2.3  11.1     1
10   5.1   2.3  20.0    10
11   5.1   2.3  31.0    11
12   5.1   2.3   5.0     0

如果有更高效的写法或方法,请大家指教下,谢谢。

函数为了逻辑清楚,我分了很多行,

def fun1(x):
    count=0
    e=x.iloc[-1] //取最后一位
    d=x[::-1] //反转数组
    d=d[1:] //去掉当前数字,就是e本身
    for t in d:
        if e>t:
            count+=1
        else:
            return count
            break
            
    return count

    
df['Count'] = df.col3.expanding(1).apply(lambda x: np.sum(fun1(x))).astype('int') 

col1 col2 col3 Count
0 5.5 2.5 10.0 0
1 2.0 4.5 1.0 0
2 2.5 5.2 8.0 1
3 4.5 5.8 4.8 0
4 4.6 6.3 9.6 3
5 4.1 6.4 9.0 0
6 5.1 2.3 3.0 0
7 5.1 2.3 11.1 7
8 5.1 2.3 10.0 0
9 5.1 2.3 11.1 1
10 5.1 2.3 20.0 10
11 5.1 2.3 31.0 11
12 5.1 2.3 5.0 0

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏