【问题标题】:Multiple & (and) condition not working properly for pandas dataframe多个 & (and) 条件不适用于 pandas 数据框
【发布时间】:2017-10-16 11:59:42
【问题描述】:

我有两个数据集——structured_data(有 4000 多条记录)和 record_data(有 400 条记录)。我正在尝试比较与结构化数据匹配的记录数据中存在的所有记录。

我通过使用以下条件使用两个数据集中的一些通用属性来做到这一点 -

filter_df = record_data[record_data.UnitNumber.isin(structured_data.UnitNumber) & record_data.price.isin(structured_data.price) & record_data.zipcode.astype(int).isin(structured_data.zipcode.astype(int)) & record_data.bedrooms.isin(structured_data.bedrooms) & record_data.bathrooms.isin(structured_data.bathrooms)]

此条件不仅仅给出对上述每个条件都成立的那些记录。虽然结果中的许多记录确实遵循条件但不是全部。我确保上述属性的数据类型在两个数据集中都是相同的。

我想要实现的是整合两个数据集,并最终让一个数据集提供所有独特的记录。

想知道代码是否有任何问题。如果需要,将很乐意分享数据集。谢谢!

【问题讨论】:

    标签: python pandas conditional conditional-formatting data-science


    【解决方案1】:

    这个例子是否说明了您的问题?更准确地说,最后的输出是您所期望的吗?

    In [1]: import pandas as pd
    
    In [2]: record_data = pd.DataFrame([[1,2,'a'],[2,6,'b'],[2,2,'c']], columns=['bedrooms', 'bathrooms', 'something_else'])
    
    In [3]: record_data
    Out[3]: 
       bedrooms  bathrooms something_else
    0         1          2              a
    1         2          6              b
    2         2          2              c
    
    In [4]: structured_data = pd.DataFrame([[1,2,'d'],[2,3,'e'],[1,3,'e']], columns=['bedrooms', 'bathrooms', 'something_else'])
    
    In [5]: structured_data
    Out[5]: 
       bedrooms  bathrooms something_else
    0         1          2              d
    1         2          3              e
    2         1          3              e
    
    In [6]: record_data[record_data.bedrooms.isin(structured_data.bedrooms) & record_data.bathrooms.isin(structured_data.bathrooms)]
    Out[6]: 
       bedrooms  bathrooms something_else
    0         1          2              a
    2         2          2              c
    

    编辑:

    根据您在下面的回答,问题是您要独立检查每一列。你得到记录{'bedrooms': 2, 'bathrooms': 6},因为structured_data 包含一行bedrooms=2,还包含一行bathrooms=6。您的条件不需要它是同一行。

    让我们举一个更大的例子。

    In [1]: import pandas as pd
    
    In [3]: structured_data = pd.DataFrame([[1,2,'d'],[2,3,'e'],[1,3,'e'],[1,6,'e']], columns=['bedrooms', 'bathrooms', 'something_else'])
    
    In [4]: structured_data
    Out[4]: 
       bedrooms  bathrooms something_else
    0         1          2              d
    1         2          3              e
    2         1          3              e
    3         1          6              e
    
    In [5]: record_data = pd.DataFrame([[1,2,'a'],[2,6,'b'],[2,2,'c'],[1,8,'g'],[4,2,'h']], columns=['bedrooms', 'bathrooms', 'something_else'])
    
    In [6]: record_data
    Out[6]: 
       bedrooms  bathrooms something_else
    0         1          2              a
    1         2          6              b
    2         2          2              c
    3         1          8              g
    4         4          2              h
    

    现在让我们分解record_data[record_data.bathrooms.isin(structured_data.bathrooms) & record_data.bedrooms.isin(structured_data.bedrooms)],看看会发生什么。

    In [7]: record_data.bathrooms.isin(structured_data.bathrooms)
    Out[7]: 
    0     True
    1     True
    2     True
    3    False
    4     True
    Name: bathrooms, dtype: bool
    

    请注意,索引是record_data 的索引。输出没有说明匹配了structured_data 的哪些行。

    In [8]: record_data.bedrooms.isin(structured_data.bedrooms)
    Out[8]: 
    0     True
    1     True
    2     True
    3     True
    4    False
    Name: bedrooms, dtype: bool
    

    同样,我们没有关于 structured_data 行的信息。

    In [9]: record_data.bathrooms.isin(structured_data.bathrooms) & record_data.bedrooms.isin(structured_data.bedrooms)
    Out[9]: 
    0     True
    1     True
    2     True
    3    False
    4    False
    dtype: bool
    
    In [10]: record_data[record_data.bathrooms.isin(structured_data.bathrooms) & record_data.bedrooms.isin(structured_data.bedrooms)]
    Out[10]: 
       bedrooms  bathrooms something_else
    0         1          2              a
    1         2          6              b
    2         2          2              c
    

    想知道代码有没有问题。

    你现在明白什么问题了吗?


    我想要实现的是整合两个数据集,最终让一个数据集提供所有独特的记录。

    澄清一下,您希望所有记录都出现在任一数据集中吗?还是只有两个数据集中的记录?

    假设是前者。

    一些想法:

    1. 鉴于两个数据集都很小,您可以使用 Python sets 并计算并集。

      In [28]: { tuple(rec) for rec in record_data[['bedrooms', 'bathrooms']].values.tolist() }
      Out[28]: {(1, 2), (1, 8), (2, 2), (2, 6), (4, 2)}
      
    2. 您可以连接您的数据集(假设它们具有相同的列)并使用drop_duplicates 来获得唯一的组合。 Merge, join, and concatenate 上的文档有很多例子。


    编辑 2:

    根据您的新答案,您可以使用merge() 执行相当于 SQL inner join 的操作:

    In [12]: pd.merge(left=record_data, right=structured_data.drop('something_else', axis=1), how='inner', on=['bedrooms', 'bathrooms'])
    Out[12]: 
       bedrooms  bathrooms something_else
    0         1          2              a
    

    【讨论】:

    • 是的,最后的输出是我所期待的
    • 如果我在 strucutured_data 中添加 (1,6,'e),上面的代码将不起作用。基本上它单独检查条件。我正在寻找的是如果卧室匹配,则匹配相同记录的浴室,而不是查看整个数据框。有意义吗?
    • 感谢 Laurie 抽出时间在这里澄清我的问题。我知道条件不是检查所有属性是否与同一记录匹配,而是考虑所有条件对每个属性都适用。我试图实现的是将 400 条记录与具有 4000 条记录的数据集匹配,如果它们匹配(基于上面的条件/属性),那么它们被认为是一个记录,如果它们不匹配,那么它是一个单独的记录。
    • 我仍然会尝试找到一种解决方法来使这种方法发挥作用,在我最终继续探索合并、连接和连接之前,我可以匹配两个数据集中的某些常见属性。再次感谢您!
    • @ShobhitTalwar 使用上面的第二个例子,你想要什么输出?
    猜你喜欢
    • 2018-06-15
    • 2014-12-15
    • 1970-01-01
    • 2020-08-29
    • 2017-04-01
    • 2022-11-22
    • 1970-01-01
    • 2020-05-21
    • 2021-04-22
    相关资源
    最近更新 更多