pandas复杂过滤其他行中的内容

时间:2018-02-16 14:01:47

标签: python pandas

我有一个DataFrame和下一个

category, start, end
c1, 100,200
c1, 101, 180 <- this one should be deleted since it is contained in the prev
c2, 10,40
c2, 35, 45 <- c2 should both be kept 
c3, 50,100
c3, 60,100 <- again, deleted

所以结果应该是

category, start, end
c1, 100,200
c2, 10,40
c2, 35, 45
c3, 50,100

我需要过滤嵌套元素(嵌套意味着:元素是一维向量,因此start和end在另一个元素的范围内)具有相同的类别,同时保持较大的元素。由于这些数据帧的长度约为100000,因此使用我目前的方法需要一段时间。

for idx, row in df.iterrows():
    #filter all that are nested into this
    res = df[(df.category == row.category) & (df.start >= row.start) & (df.end <= row.end) & (df.index != idx) ]
    l.append(res)
res = pd.concat(l)
#remove all nested
df.drop(res.index,inplace=True)

在循环的每个步骤中,它获取当前元素的所有嵌套元素并将其添加到数据帧列表中,然后删除所有这些元素。

你能想到更好的方法吗?

1 个答案:

答案 0 :(得分:5)

一种可能的解决方案是按列category进行交叉连接:

df1 = df.reset_index()
df1 = pd.merge(df1, df1, on='category')
m = ((df1.start_x >= df1.start_y) & (df1.end_x <= df1.end_y) & (df1.index_x != df1.index_y))
idx = df1.loc[m, 'index_x']
print (df.drop(idx))
  category  start  end
0       c1    100  200
2       c2     10   40
3       c2     35   45
4       c3     50  100