python - Pandas : Delete rows based on other rows

标签 python pandas dataframe

我有一个看起来像这样的 Pandas 数据框:

qseqid  sseqid  qstart    qend
2         1     125       345
4         1     150       320
3         2     150       450
6         2     25        300
8         2     50        500

我想根据具有这些条件的其他行值删除行:如果另一行 (r2) 存在相同的 sseqid,则必须删除行 (r1)和 r1[qstart] > r2[qstart]r1[qend] < r2[qend] .

这对 Pandas 来说可能吗?

最佳答案

df  = pd.DataFrame({'qend': [345, 320, 450, 300, 500],
 'qseqid': [2, 4, 3, 6, 8],
 'qstart': [125, 150, 150, 25, 50],
 'sseqid': [1, 1, 2, 2, 2]})

def remove_rows(df):
    merged = pd.merge(df.reset_index(), df, on='sseqid')
    mask = ((merged['qstart_x'] > merged['qstart_y']) 
            & (merged['qend_x'] < merged['qend_y']))
    df_mask = ~df.index.isin(merged.loc[mask, 'index'].values)
    result = df.loc[df_mask]
    return result

result = remove_rows(df)
print(result)

产量

   qend  qseqid  qstart  sseqid
0   345       2     125       1
3   300       6      25       2
4   500       8      50       2

想法是使用pd.merge 将每对行组成一个DataFrame 使用相同的 sseqid:

In [78]: pd.merge(df.reset_index(), df, on='sseqid')
Out[78]: 
    index  qend_x  qseqid_x  qstart_x  sseqid  qend_y  qseqid_y  qstart_y
0       0     345         2       125       1     345         2       125
1       0     345         2       125       1     320         4       150
2       1     320         4       150       1     345         2       125
3       1     320         4       150       1     320         4       150
4       2     450         3       150       2     450         3       150
5       2     450         3       150       2     300         6        25
6       2     450         3       150       2     500         8        50
7       3     300         6        25       2     450         3       150
8       3     300         6        25       2     300         6        25
9       3     300         6        25       2     500         8        50
10      4     500         8        50       2     450         3       150
11      4     500         8        50       2     300         6        25
12      4     500         8        50       2     500         8        50

merged 的​​每一行包含来自 df 的两行的数据。然后,您可以使用

比较每两行
mask = ((merged['qstart_x'] > merged['qstart_y']) 
        & (merged['qend_x'] < merged['qend_y']))

并在df.index中找到不符合这个条件的标签:

df_mask = ~df.index.isin(merged.loc[mask, 'index'].values)

并选择那些行:

result = df.loc[df_mask]

请注意,这假定 df 具有唯一索引。

关于python - Pandas : Delete rows based on other rows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39223638/

相关文章:

python - 为什么Python中的列表可以与整数进行比较

python - 在 Linux 上执行时 Xlsxwriter header 格式不出现

python - 格式化 Pandas Dataframe 以绘制图形

python - 无法在 Pandas 中读取 Excel 文件

python - 如何在 PySpark 的 UDF 中返回 "Tuple type"?

python - pandas - 如何在有条件的 groupby 中创建多列?

python - Pandas:删除数据框中具有 NaN 阈值的前导行

python - Bloomberg APIv3 获取引用数据覆盖

python - Python 中的二叉树

javascript - 如何使用不变的 URL 抓取多个页面 - Python 3