提高通过熊猫数据框循环的效率

时间:2018-10-31 00:54:30

标签: python pandas

我猜想有一种更有效的方法可以进行比较。

目前,我有两个熊猫DataFrame。

DataFrame A看起来像这样:

    Location    Tier    Other
0   100         1       'Blah'
1   200         1       'Blah'
2   10          1       'Blah'
3   30          1       'Blah'
4   500         1       'Blah'

DataFrame B看起来像这样:

    Start   Stop    Tier    Other
0   400     600     1       'Blah'
1   5       20      2       'Blah'

我想找到Location > StartLocation < EndTier匹配的所有行。因此,在上面的示例中,DataFrame A的第4行的Location大于400但小于600,并且Tier为in这两个DataFrame,因此应该以某种方式返回,例如附加到最终的DataFrame。

这就是我现在进行比较的方式:

for i in A():
    matching = matching.append(B[(B.Tier == i.Tier) & (B.Start < i.Location) & (B.Stop > i.Location)], ignore_index=True)
return matching

由于我的代码运行得很慢,是否有更快的方法来完成此操作?

3 个答案:

答案 0 :(得分:1)

我想到的第一件事是对数据集进行排序(例如,按位置排序,然后对A组按层排序)。然后,您可以使用二进制搜索算法来大大缩短搜索时间。

答案 1 :(得分:1)

使用numpy广播

s1=df2.Start.values<df.Location.values[:,None]
s2=df2.Stop.values>df.Location.values[:,None]
s1&s2
Out[110]: 
array([[False, False],
       [False, False],
       [False,  True],
       [False, False],
       [ True, False]])
df[(s1&s2).any(1)]
Out[111]: 
   Location  Tier   Other
2        10     1  'Blah'
4       500     1  'Blah'

答案 2 :(得分:1)

如果B中有多个具有相同层的行,则可以定义StartStop

def matching(row):
    # use the first one
    cur_row = B[B.Tier == row.Tier].iloc[0]
    Start = cur_row.Start
    Stop = cur_row.Stop
    return row.Location > Start and row.Location < End

A[A.apply(matching, axis=1)]

其他示例:

def matching(row):
    # other example
    cur_rows = B[B.Tier == row.Tier]
    Start = cur_rows.Start.min()
    Stop = cur_rows.Stop.max()
    return row.Location > Start and row.Location < End

A[A.apply(matching, axis=1)]