【问题标题】:How to check if panda dataframe group have same data如何检查熊猫数据框组是否具有相同的数据
【发布时间】:2018-11-13 12:52:07
【问题描述】:

我有一个如下的熊猫数据框

id  name  Base   field1    field2           field3
1   AA     Y      Yes      Consumer         Not Applicable 
1   BB     N      Yes      Consumer         Not Applicable 
2   CC     Y      Yes      Consumer         Not Applicable 
2   DD     N      Yes      Not Applicable   Not Applicable 
2   EE     N      No       Not Applicable   Modified
3   FF     Y      Yes      Not Applicable   Applicable 
3   GG     N      Yes      Not Applicable   Not Applicable 
3   HH     N      Yes      Not Applicable   Not Applicable 

预期的结果是根据ID列对这个dataframe进行分组,并检查其他所有列上的数据是否是每个组中的相同数据,最后写入结果。

我试过这个来验证每个组的数据,但它总是说 TRUE

代码:

result_list=[]
for col in df.columns:
        result = df.groupby(level=0)[col].apply(lambda x: len(set(x))==1)
        result_list.append(result)

final = pd.concat(result_list,1)

预期结果是

id  name     field1   field2           field3           Error
1   AA       Yes      Consumer         Not Applicable   Pass 
1   BB       Yes      Consumer         Not Applicable   Pass
2   CC       Yes      Consumer         Not Applicable   field1, field2, field3 mismatch for ID: 2
2   DD       Yes      Not Applicable   Not Applicable   field1, field2, field3 mismatch for ID: 2
2   EE       No       Not Applicable   Modified         field1, field2, field3 mismatch for ID: 2
3   FF       Yes      Not Applicable   Applicable       field3 mismatch for ID: 3
3   GG       Yes      Not Applicable   Not Applicable   field3 mismatch for ID: 3
3   HH       Yes      Not Applicable   Not Applicable   field3 mismatch for ID: 3

有什么帮助吗?

【问题讨论】:

  • 你想要的结果是什么,只有id = 1通过了你的测试?
  • 嗨,我已经更新了数据框和预期结果。让我知道它是否有帮助

标签: python-3.x pandas dataframe pandas-groupby


【解决方案1】:

你可能会得到你想要的代码(假设df有名为id的索引):

def handler(df):
    for col in ['field1', 'field2', 'field3']:
        if df.loc[:, col].nunique() > 1:
            return 'error in {} for id {}'.format(col, df.index[0])
    else:
        return 'pass'

result = df.groupby(level=0).apply(handler)
result = df.reset_index().merge(result.to_frame().reset_index(), on='id')

result 是:

   id name field1          field2          field3                         0
0   1   AA    Yes        Consumer  Not Applicable                      pass
1   1   BB    Yes        Consumer  Not Applicable                      pass
2   2   CC    Yes        Consumer  Not Applicable  error in field1 for id 2
3   2   DD    Yes  Not Applicable  Not Applicable  error in field1 for id 2
4   2   EE     No  Not Applicable        Modified  error in field1 for id 2
5   3   FF    Yes  Not Applicable      Applicable  error in field3 for id 3
6   3   GG    Yes  Not Applicable  Not Applicable  error in field3 for id 3
7   3   HH    Yes  Not Applicable  Not Applicable  error in field3 for id 3

EDIT - 处理程序中的次要版本

def handler(df):
    cols = list()
    for col in ['field1', 'field2', 'field3']:
        if df.loc[:, col].nunique() > 1:
            cols.append(col)
    if cols:
        return 'error in {} for id {}'.format(', '.join(cols), df.index[0])
    else:
        return 'pass'

【讨论】:

  • 嗨,Poolka,然而,这段代码几乎满足了预期的结果。但是,在错误列上,它没有显示数据是否在多个字段上不匹配。对于 id 2:它应该写为 ID:2 的 Field1、Field2 和 Field 3 不匹配。有什么想法吗?
  • 数据比较总是发生在列表的第一个字段上,其他字段被跳过。
  • @Osceria 答案中的代码是工作和执行非常接近您想要的东西的基础。随意修改它(列名、处理程序等)以满足您的期望。关于评论中的问题 - 检查编辑添加。
  • 稍作改动后,它可以完美地满足我的要求。我刚刚发布了另一篇类似问题的帖子,但有额外的检查。 stackoverflow.com/questions/53295685/…
【解决方案2】:

您可以groupby id 然后agg 每列计算每个组的unique 值的数量,然后您就知道该数字大于 1 是错误的:

df[df.columns.drop('name')].groupby('id').agg(lambda x: len(x.unique()))>1

有了这个输出,你可以根据它来构造你的字符串。

    field1  field2  field3
id          
1   False   False   False
2   True    True    True
3   False   False   True

【讨论】:

  • -这有帮助。如果要验证的列名在不同的迭代中不同怎么办。我在一个 for 循环中运行这部分,该循环使用不同的数据帧(df1,df2)进行迭代,并且 df、df2 和 df3 的列是不同的。所以,我不想对其他数据帧不断变化的字段名称进行硬编码
  • 查看编辑,您可以传递列列表删除“名称”列,然后您可以传递任何其他数量的字段..
  • 好的。如果我向数据框(已编辑)添加另一列(基础)。对于基于 ID 的每个组,将只有一个“Y”,组中的其他行将是“N”。在这里,Base='Y' 的行的值应该是参考,而 Base 'N' 的其他行应该根据它进行验证。每行上不同的列应被记录为错误列。有什么想法吗?
  • 这完全改变了问题和解决方案的范围,我建议用不同的输入和输出编写另一个问题以进行澄清..
猜你喜欢
  • 2020-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-02
  • 2022-07-21
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
相关资源
最近更新 更多