如何向量化Pandas DataFrame前列值搜索

时间:2019-05-11 09:12:13

标签: python pandas dataframe vectorization

我只想向前搜索pandas数据框列中的目标值,如果找到更大的值,那么我想将索引差异记录为结果列。我设法通过两个内部的for循环来做到这一点,但速度非常慢。

这是我想在一个简化示例中实现的。

import pandas as pd

d = {
    'Value'  : [8,9,10,12,16,13,11,7,12,18],
    'Target' : [12,12,11,15,19,11,16,11,17,18]
    }
df = pd.DataFrame(data=d)


>>> df

   Target  Value
0      12      8
1      12      9
2      11     10
3      15     12
4      19     16
5      11     13
6      16     11
7      11      7
8      17     12
9      18     18

我们的第一个值是8,而我们的目标值是12。我们在“值”列中期待超过该目标值的值。我们在第4行中找到它的值为16。我要记录的是索引差异,即4-0 = 4。

下一个值是9,目标值又是12。我们期待这些值,然后再次找到具有值16的第4行。现在索引差是4-1 = 3

让我们跳到第4行。我们开始寻找从索引5开始的目标值。如果找不到任何值,则结果为0。

这是我要访问的结果列。

   Target  Value  Result
0      12      8       4
1      12      9       3
2      11     10       1
3      15     12       1
4      19     16       0
5      11     13       3
6      16     11       3
7      11      7       1
8      17     12       1
9      18     18       0

可以不用for循环吗?

2 个答案:

答案 0 :(得分:4)

使用numpy广播进行比较,将numpy上三角矩阵设置为False,通过numpy.argmax获得第一个True索引,通过arange减去并设置为{{1} }所有底片:

0

答案 1 :(得分:1)

您可以将其缩短为一个for循环。使用Series.first_valid_index()和布尔条件:

df['Result'] = 0
for i, target in enumerate(df.Target):
    val = df[(df.Value>target) & (df.index>i)]['Value'].first_valid_index()
    if val is not None:
        df.at[i, 'Result'] = val - i
df
   Value    Target  Result
0   8        12      4
1   9        12      3
2   10       11      1
3   12       15      1
4   16       19      0
5   13       11      3
6   11       16      3
7   7        11      1
8   12       17      1
9   18       18      0

条件将查找Value大于目标的每一行,但也仅在目标的索引之后,并且first_valid_index将返回满足条件的第一个索引。