我猜想有一种更有效的方法可以进行比较。
目前,我有两个熊猫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 > Start
和Location < End
和Tier
匹配的所有行。因此,在上面的示例中,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
由于我的代码运行得很慢,是否有更快的方法来完成此操作?
答案 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中有多个具有相同层的行,则可以定义Start
和Stop
。
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)]