我在 pandas 中有两个 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 的行:
- 名称应同时出现在 df1 和 df2 中
- 名称从开始到停止的范围与其他 DataFrame 中该名称从开始到停止的范围重叠
这将给出:
Name start stop
0 B 124 200
1 C 159 200
2 D 12 24
3 D 26 30
4 E 110 160
地点:
- A 已被删除,因为 df2 中没有 A
- B 被保留,因为 df2 中 B 的起点和终点嵌套在 df1 中 B 的起点和终点
- df1 的一个 C 已被删除,因为它的值与 df2 不重叠,而另一个则被保留,因为它嵌套在 df2 中 C 的开始和停止范围内
- 两个 D 都被保留,因为它们都与 df2 中 D 的范围重叠
- E 被保留,因为它的范围与 df2 中的 E 重叠
任何帮助将不胜感激!
最佳答案
为了解决您的问题,我应用了一种类似于 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: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or 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 .
关于python - 根据 pandas 中的其他数据帧过滤一个数据帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58741434/