pandas 数据帧的多个 &(和)条件无法正常工作

Multiple & (and) condition not working properly for pandas dataframe

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

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

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)]

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

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

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

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

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

Wondering if there is anything wrong with the code.

你明白这是怎么回事了吗?


What I am trying to achieve is integrate both the datasets and eventually have one dataset giving all the unique records.

澄清一下,您想要出现在任一数据集中的所有记录?或者只有两个数据集中的记录?

假设是前者。

一些想法:

  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 to get unique combinations. The doc on 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