【问题标题】:Only allow one to one mapping between two columns in pandas dataframe只允许熊猫数据框中两列之间的一对一映射
【发布时间】:2014-05-18 03:02:54
【问题描述】:

我有一个两列数据框 df,每一行都是不同的,一列中的一个元素可以映射到另一列中的一个或多个元素。我想过滤掉那些元素。因此,在最终数据框中,一列中的一个元素仅映射到另一列中的唯一元素。

我正在做的是按一列分组并计算重复项,然后删除计数超过 1 的行。然后对另一列再次执行此操作。我想知道是否有更好、更简单的方法。

谢谢


edit1:我刚刚意识到我的解决方案是错误的,删除 A 列中的多映射元素会减少 B 列中的映射数量,请考虑以下示例:

甲乙

1 4

1 3

2 4

1 映射到 3,4 ,因此应该删除前两行,4 映射到 1,2。决赛桌应该是空的。但是,我的解决方案将保留最后一行。

谁能给我一个快速简单的解决方案?谢谢

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    好吧,您可以执行以下操作:

    >>> df
    
       A  B
    0  1  4
    1  1  3
    2  2  4
    3  3  5
    

    如果没有其他行具有“A”值且没有其他行具有“B”值,则您只想保留一行。在此示例中,只有第三行满足这些条件:

    >>> Aone = df.groupby('A').filter(lambda x: len(x) == 1)
    >>> Bone = df.groupby('B').filter(lambda x: len(x) == 1)
    >>> Aone.merge(Bone,on=['A','B'],how='inner')
    
        A  B
     0  3  5
    

    解释:

    >>> Aone = df.groupby('A').filter(lambda x: len(x) == 1)
    >>> Aone
    
       A  B
    2  2  4
    3  3  5
    

    以上内容仅根据“A”列获取可能允许的行。

    >>> Bone = df.groupby('B').filter(lambda x: len(x) == 1)
    >>> Bone
    
       A  B
    1  1  3
    3  3  5
    

    以上内容仅根据“B”列获取可能允许的行。然后合并交叉点会留下只满足两个条件的行:

    >>> Aone.merge(Bone,on=['A','B'],how='inner')
    

    注意,您也可以使用groupby/transform 做类似的事情。但是转换往往很慢,所以我没有这样做。

    【讨论】:

    • 是的,我用 groupby/transform 做到了。感谢您的回答,我一直想知道我应该使用哪一个。例如,我总是喜欢使用 .apply() 之类的东西,因为它非常通用且功能强大,但可能会很慢。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-19
    • 2022-11-18
    • 1970-01-01
    • 2017-05-13
    • 2019-05-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多