我有以下示例数据帧:

d = {'col1': [4, 2, 8, 4, 3, 7, 6, 9, 3, 5]}
df = pd.DataFrame(data=d)
df


    col1
0   4
1   2
2   8
3   4
4   3
5   7
6   6
7   9
8   3
9   5

我需要在这个数据帧上加上col2,这个新列的值将通过比较col1个值(来自不同的行)来设置,如下所述.每行col2个将设置如下:

df.loc[0, "col2"]会说出df.loc[1, "col1"]df.loc[2, "col1"]df.loc[3, "col1"]中有多少大于df.loc[0, "col1"].

df.loc[1, "col2"]会说出df.loc[2, "col1"]df.loc[3, "col1"]df.loc[4, "col1"]中有多少大于df.loc[1, "col1"].

df.loc[2, "col2"]会说出df.loc[3, "col1"]df.loc[4, "col1"]df.loc[5, "col1"]中有多少大于df.loc[2, "col1"].

以此类推.

如果index N之后没有剩下3 rows个,则col2值将被设置为-1.

最终结果如下所示:

    col1    col2
0   4       1
1   2       3
2   8       0
3   4       2
4   3       3
5   7       1
6   6       1
7   9       -1
8   3       -1
9   5       -1

我需要一个函数,它将接受DataFrame作为输入,并将通过添加如上所述的新列返回DataFrame.

在上面的示例中,考虑了接下来的3行.但这需要是可配置的,并且应该是完成工作的函数的输入.

速度在这里很重要,因此不希望用于循环.

在Python中,如何以最有效的方式完成这项工作?

推荐答案

您需要反转rolling才能将这些值与下一个值进行比较:

N = 3
df['col2'] = (df.loc[::-1, 'col1']
                .rolling(N+1)
                .apply(lambda s: s.iloc[:-1].gt(s.iloc[-1]).sum())
                .fillna(-1, downcast='infer')
             )

或者,使用numpy.lib.stride_tricks.sliding_window_view:

import numpy as np
from numpy.lib.stride_tricks import sliding_window_view as swv

N = 3
df['col2'] = np.r_[(df['col1'].to_numpy()[:-N, None]
                    < swv(df['col1'], N)[1:]  # broadcasted comparison
                    ).sum(axis=1),            # count True per row
                   -np.ones(N, dtype=int)]    # add missing -1

输出:

   col1  col2
0     4     1
1     2     3
2     8     0
3     4     2
4     3     3
5     7     1
6     6     1
7     9    -1
8     3    -1
9     5    -1

Python相关问答推荐

我在使用fill_between()将最大和最小带应用到我的图表中时遇到问题

Pandas 在最近的日期合并,考虑到破产

DataFrame groupby函数从列返回数组而不是值

如何使用matplotlib在Python中使用规范化数据和原始t测试值创建组合热图?

如何过滤包含2个指定子字符串的收件箱列名?

数据抓取失败:寻求帮助

PyQt5,如何使每个对象的 colored颜色 不同?'

avxspan与pandas period_range

如何设置视频语言时上传到YouTube与Python API客户端

使用groupby方法移除公共子字符串

在Python中使用if else或使用regex将二进制数据如111转换为001""

使用tqdm的进度条

Tensorflow tokenizer问题.num_words到底做了什么?

每次查询的流通股数量

如何为需要初始化的具体类实现依赖反转和接口分离?

高效生成累积式三角矩阵

文本溢出了Kivy的视区

多索引数据帧到标准索引DF

Scipy.linprog的可行性有问题吗?(A_ub@x0<;=b_ub).all()为True-但是-linprog(np.zeros_like(X0),A_ub=A_ub,b_ub=b_ub)不可行

为什么内置的sorted()对于一个包含降序数字的列表来说,如果每个数字连续出现两次,会变慢?