【问题标题】:Pandas : Delete rows based on other rowsPandas:根据其他行删除行
【发布时间】:2016-09-19 20:57:24
【问题描述】:

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

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

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

熊猫可以做到这一点吗?

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:
    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 具有唯一索引。

    【讨论】:

    • @unutbu - 这是合并 df.reset_index() 和 df 的绝佳想法 :-)
    • 这太棒了!非常感谢:)
    • 这是一个非常有帮助和启发性的答案,谢谢@unutbu!
    猜你喜欢
    • 2019-05-21
    • 1970-01-01
    • 2017-07-07
    • 2020-10-06
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 1970-01-01
    相关资源
    最近更新 更多