我在熊猫中有两个DataFrame:
import pandas as pd
df1 = pd.DataFrame({'Name': ["A", "B", "C", "C","D","D","E"],
'start': [50, 124, 1, 159, 12, 26,110],
'stop': [60, 200, 19, 200, 24, 30,160]})
df2 = pd.DataFrame({'Name': ["B", "C","D","E"],
'start': [126, 143, 19, 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的行:
这将给出:
Name start stop
0 B 124 200
1 C 159 200
2 D 12 24
3 D 26 30
4 E 110 160
位置:
任何帮助将不胜感激!
答案 0 :(得分:1)
为解决您的问题,我采用了一种类似于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", "C","D","D","E"],
'start': [50, 124, 1, 159, 12, 26,110],
'stop': [60, 200, 19, 200, 24, 30,160]})
df2 = pd.DataFrame({'Name': ["B", "C","D","E"],
'start': [126, 143, 19, 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上演示。
答案 1 :(得分:0)
对于感兴趣的人,我想出了一种方法...
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
完成工作,尽管有点笨拙。
如果有人可以提出一种不太杂乱的方式,将会很感兴趣!