根据熊猫中的其他数据框过滤一个数据框

我在熊猫中有两个DataFrame:

import pandas as pd

df1 = pd.DataFrame({'Name': ["A","B","C","D","E"],'start': [50,124,1,159,12,26,110],'stop': [60,200,19,24,30,160]})
df2 = pd.DataFrame({'Name': ["B",'start': [126,143,159],'stop': [129,220,27,200]})

print(df1)

  Name  start  stop
0    A     50    60
1    B    124   200
2    C      1    19
3    C    159   200
4    D     12    24
5    D     26    30
6    E    110   160

print(df2)

  Name  start  stop
0    B    126   129
1    C    143   220
2    D     19    27
3    E    159   200

我要使用以下条件过滤df1以删除基于df2的行:

  1. 名称应同时出现在df1和df2中
  2. 在另一个DataFrame中,该名称从开始到终止的范围与该名称从开始到终止的范围重叠

这将给出:

  Name  start  stop
0    B    124   200
1    C    159   200
2    D     12    24
3    D     26    30
4    E    110   160

位置:

  • 由于df2中没有A,因此A已被删除
  • B保持不变,因为df2中B的起始和终止与df1中B的起始和终止嵌套
  • 由于df1的一个C与df2不重叠,因此删除了一个C,而保留了另一个,因为它嵌套在df2中C的起始和终止范围内
  • 两个D都被保留,因为它们都与df2中的D的范围重叠
  • E被保留,因为其范围与df2中的E重叠

任何帮助将不胜感激!

s173682752 回答:根据熊猫中的其他数据框过滤一个数据框

为解决您的问题,我采用了一种类似于SQL的方式来模仿以下查询:

SELECT
  df.Name,df.start_x AS start,df.stop_x AS stop
FROM (
  SELECT
    df1.Name,df1.start AS start_x,df1.stop AS stop_x,df2.start AS start_y,df2.stop AS stop_y
    FROM df1
    INNER JOIN df2
      ON df1.Name = df2.Name
) AS df
WHERE (df.stop_y >= df.start_x) AND (df.stop_x >= df.start_y)

此查询已转换为使用pandas.merge方法的以下代码片段。请注意,必须在表达式(df.stop_y> = df.start_x) & (df.stop_x> = df.start_y)中使用括号。没有它们,代码将引发异常

  

ValueError:系列的真值不明确。使用a.empty,a.bool(),a.item(),a.any()或a.all()。

import pandas as pd

df1 = pd.DataFrame({'Name': ["A","B","C","D","E"],'start': [50,124,1,159,12,26,110],'stop': [60,200,19,24,30,160]})
df2 = pd.DataFrame({'Name': ["B",'start': [126,143,159],'stop': [129,220,27,200]})
df = pd.merge(df1,df2,on=['Name'])
df = df[(df.stop_y >= df.start_x) & (df.stop_x >= df.start_y)]
df.rename(columns={'start_x':'start','stop_x':'stop'},inplace=True)
df.drop(['start_y','stop_y'],axis=1,inplace=True)
df.reset_index(drop=True,inplace=True)
print(df)

输出:

  Name  start  stop
0    B    124   200
1    C    159   200
2    D     12    24
3    D     26    30
4    E    110   160

Repl.it上演示。

,

对于感兴趣的人,我想出了一种方法...

df3=[]
for index1,row1 in df1.iterrows():
    for index2,row2 in df2.iterrows():
        if row1["Name"] == row2["Name"]:
            x = range(row1["start"],row1["stop"])
            x = set(x)
            y = range(row2["start"],row2["stop"])
            if len(x.intersection(y)) > 0:
                df3.append(row1)
df3 = pd.DataFrame(df3).reset_index(drop=True)
print(df3)

  Name  start  stop
0    B    124   200
1    C    159   200
2    D     12    24
3    D     26    30
4    E    110   160

完成工作,尽管有点笨拙。

如果有人可以提出一种不太杂乱的方式,将会很感兴趣!

本文链接:https://www.f2er.com/3147741.html

大家都在问