在pandas数据帧中对两列进行条件测试和比较

时间:2017-10-04 16:32:08

标签: python pandas dataframe boolean-logic

我正在尝试对具有两列的数据帧执行条件检查,如下所示:除非两个值相等,否则任一列的内容都不能在另一列中 - 不存在两个列中都存在值的实例价值观不相等。

在例如在下面,条件得到满足。虽然alternahaircare.com在两个列中 - domain和credit_domain,但唯一的情况是这两个值相等。

Out[198]: df
                            domain               credit_domain
2              alternahaircare.com         alternahaircare.com
3    alternahaircare.myshopify.com         alternahaircare.com
4         shop.alternahaircare.com         alternahaircare.com
5                 americancrew.com            americancrew.com

下面是上面两个修改过的例子,其中我不满足我想要满足的条件:

在这一篇文章中,您可以看到domain = alternahaircare和credit_domain = americancrew.com。这是错误的 - 现在alternahaircare.com出现在两个列中,但有一个实例,其中credit_domain列中的值与域列不匹配。

Out[199]: df
                            domain               credit_domain
2              alternahaircare.com            americancrew.com
3    alternahaircare.myshopify.com         alternahaircare.com
4         shop.alternahaircare.com         alternahaircare.com
5                 americancrew.com            americancrew.com

以下实例也是错误的 - 不符合我想要满足的条件。虽然有一个alternahaircare.com == alternahaircare.com的实例,但也有一个alternahaircare.com的实例被分配给一个本身不是的值,即americacrew.com

Out[198]: df
                            domain               credit_domain
2              alternahaircare.com         alternahaircare.com
3    alternahaircare.myshopify.com         alternahaircare.com
4         shop.alternahaircare.com         alternahaircare.com
5              alternahaircare.com            americancrew.com

通过检查域值的计数并识别出现两次的任何内容,可以轻松解决这些问题中的第二个问题。

第一个问题让我感到困惑。我的方法是识别潜在的问题行,然后尝试使用groupby和条件语句:

potential_error_rows = df[df.credit_domain.isin([x for x in df.credit_domain.tolist() if x in df.domain.tolist()])]

无法想到除此之外还要做什么!

2 个答案:

答案 0 :(得分:1)

如果我在列之间正确理解了您想要的映射,您只需检查domain中是否有与两者相对应的行

  • credit_domain
  • 不等于credit_domain中的行值。

喜欢这样

def is_valid(df):
    return ~(df.domain.isin(df.credit_domain) &
             (df.domain != df.credit_domain)).any()

为您的示例DataFrame返回TrueFalseFalse

答案 1 :(得分:0)

我已经很接近并找到了答案:

# This gives the suspect rows - rows of data where domain value is same as the list of credit_domain present in domain
x = df[df.domain.isin([x for x in df.credit_domain.tolist() if x in df.domain.tolist()])]

# Once I have the above, it was a simple matter of looking at those rows where domain != credit_domain
x[x.domain != x.credit_domain]