我有一个数据框看起来是这样的:

    col1
0     10
1      5
2      8
3     12
4     13
5      6
6      9
7     11
8     10
9      3
10    21
11    18
12    14
13    16
14    30
15    45
16    31
17    40
18    38

对于‘col1’中的每个单元格,我计算一个值范围:

df['df_min'] = df.col1 - df.col1 * 0.2
df['df_max'] = df.col1 + df.col1 * 0.2

对于每个单元格都有一个范围,我想要计算过go xx个单元格(本例中为3个)中有多少个单元格在该范围内,但没有循环,因为使用我的实际模型需要很长时间.

我正在努力实现这样的结果:

    col1  df_min  df_max  counter
0     10     8.0    12.0       -1
1      5     4.0     6.0       -1
2      8     6.4     9.6       -1
3     12     9.6    14.4        1
4     13    10.4    15.6        1
5      6     4.8     7.2        0
6      9     7.2    10.8        0
7     11     8.8    13.2        2
8     10     8.0    12.0        2
9      3     2.4     3.6        0
10    21    16.8    25.2        0
11    18    14.4    21.6        1
12    14    11.2    16.8        0
13    16    12.8    19.2        2
14    30    24.0    36.0        0
15    45    36.0    54.0        0
16    31    24.8    37.2        1
17    40    32.0    48.0        1
18    38    30.4    45.6        3

下面是我能想出的(乱七八糟的)代码,但如果可能的话,我真的想要一个更快的解决方案.如有任何帮助,我们将不胜感激.

df = pd.DataFrame({"col1":[10, 5, 8, 12, 13, 6, 9, 11, 10, 3, 21, 18, 14, 16, 30, 45, 31, 40, 38]})

back = 3 # numbers of cells to check back

df['df_min'] = df.col1 - df.col1 * 0.2
df['df_max'] = df.col1 + df.col1 * 0.2

l = []
for window in df.col1.rolling(window=back+1, center=False, closed='right'):
    if window.empty:
        pass
    else:
        a = window.iloc[-1]
        range_min = a - a * 0.2
        range_max = a + a * 0.2
        c = 0
        if len(window) == back+1:
            for b in window:
                if (b >= range_min and b <= range_max):
                    c += 1
        c = c-1 # substract 1 because window includes the tested value which is always true
        l.append(c)
df1 = pd.DataFrame(l, columns=['counter'])

df = df.join(df1)

print(df)

推荐答案

具有矢量化运算的循环

Code

df['df_min'] = df.col1 - df.col1 * 0.2
df['df_max'] = df.col1 + df.col1 * 0.2
n = 3
s = pd.Series(dtype='float')
for i in range(0, n):
    s1 = df.col1.shift(i+1).ge(df['df_min']) & df.col1.shift(i+1).le(df['df_max'])
    s = s.add(s1, fill_value=0)
s[:n] = -1
df['counter'] = s

输出(df):

    col1    df_min  df_max  counter
0   10      8.0     12.0    -1.0
1   5       4.0     6.0     -1.0
2   8       6.4     9.6     -1.0
3   12      9.6     14.4    1.0
4   13      10.4    15.6    1.0
5   6       4.8     7.2     0.0
6   9       7.2     10.8    0.0
7   11      8.8     13.2    2.0
8   10      8.0     12.0    2.0
9   3       2.4     3.6     0.0
10  21      16.8    25.2    0.0
11  18      14.4    21.6    1.0
12  14      11.2    16.8    0.0
13  16      12.8    19.2    2.0
14  30      24.0    36.0    0.0
15  45      36.0    54.0    0.0
16  31      24.8    37.2    1.0
17  40      32.0    48.0    1.0
18  38      30.4    45.6    3.0



我不知道你的数据集.然而,当我测试1,000,000行和n = 10行时,这段代码只需要0.4秒.


test example

import numpy as np
df = pd.DataFrame(np.random.randint(20,100, 1000000), columns=['col1'])

Python相关问答推荐

如何在箱形图中添加绘制线的传奇?

Python键入协议默认值

如何在给定的条件下使numpy数组的计算速度最快?

连接一个rabrame和另一个1d rabrame不是问题,但当使用[...]'运算符会产生不同的结果

如何使用scipy的curve_fit与约束,其中拟合的曲线总是在观测值之下?

如何启动下载并在不击中磁盘的情况下呈现响应?

考虑到同一天和前2天的前2个数值,如何估算电力时间序列数据中的缺失值?

无论输入分辨率如何,稳定扩散管道始终输出512 * 512张图像

Python全局变量递归得到不同的结果

将标签移动到matplotlib饼图中楔形块的开始处

Python避免mypy在相互引用中从另一个类重定义类时失败

提高算法效率的策略?

为什么Python内存中的列表大小与文档不匹配?

我对这个简单的异步者的例子有什么错误的理解吗?

我可以不带视频系统的pygame,只用于游戏手柄输入吗?''

如何设置nan值为numpy数组多条件

Pandas:使列中的列表大小与另一列中的列表大小相同

当lambda函数作为参数传递时,pyo3执行

ValueError:必须在Pandas 中生成聚合值

Django REST框架+Django Channel->;[Errno 111]连接调用失败(';127.0.0.1';,6379)