获取在第二个数据框中不存在的数据框记录。
获取在第二个数据框中不存在的数据框记录。
我有两个pandas数据框,其中有一些共同的行。\n假设dataframe2是dataframe1的一个子集。\n我如何得到dataframe1中不在dataframe2中的行?\n
df1 = pandas.DataFrame(data = {'col1' : [1, 2, 3, 4, 5], 'col2' : [10, 11, 12, 13, 14]}) df2 = pandas.DataFrame(data = {'col1' : [1, 2, 3], 'col2' : [10, 11, 12]})
\ndf1\n
col1 col2 0 1 10 1 2 11 2 3 12 3 4 13 4 5 14
\ndf2\n
col1 col2 0 1 10 1 2 11 2 3 12
\n期望的结果:\n
col1 col2 3 4 13 4 5 14
在处理数据集时,有时候我们需要找到一个数据集中存在的记录,而在另一个数据集中不存在的记录。这个问题通常在数据清洗和数据匹配的过程中出现。下面将介绍出现这个问题的原因以及解决方法。
问题的原因是由于两个数据集之间的索引不一致,导致某些记录在一个数据集中存在,在另一个数据集中却不存在。这可能是由于数据收集或处理过程中的错误或不完整导致的。
为了解决这个问题,我们可以使用pandas库中的一些函数。假设我们有两个数据集df1和df2,并且假设它们的索引是一致的(不考虑实际的列值)。我们可以使用下面的代码来获取df1中存在而df2中不存在的记录:
df1[~df1.index.isin(df2.index)]
上面的代码中,`df1.index.isin(df2.index)`用于判断df1的索引是否在df2的索引中存在。`~`符号用于取反操作,即获取df1索引中不存在于df2索引中的记录。
通过上述代码,我们可以得到df1中存在而df2中不存在的记录,从而解决了我们的问题。
这种方法非常方便,可以节省我们的时间和精力。在实际的数据处理中,我们可能会遇到更复杂的情况,但是以上的方法可以作为一个基本的框架来进行处理。
总结一下,获取一个数据集中存在而另一个数据集中不存在的记录是一个常见的数据处理问题。通过使用pandas库中的函数,我们可以轻松解决这个问题。在实际的数据处理中,我们可能需要根据具体的情况进行一些调整和修改,但是以上的方法可以作为一个起点来解决这个问题。
问题:如何获取一个数据框中不存在于另一个数据框中的记录?
原因:当我们需要对两个数据框进行比较,找出在一个数据框中存在而在另一个数据框中不存在的记录时,就需要解决这个问题。
解决方法1:一种方法是通过将两个数据框进行内部合并,并存储合并结果。然后,我们可以简单地选择当一个列的值不在这个合并结果中的行:
common = df1.merge(df2,on=['col1','col2']) df1[(~df1.col1.isin(common.col1))&(~df1.col2.isin(common.col2))]
解决方法2:另一种方法是使用`isin`函数,它会产生包含`NaN`值的行,然后我们可以将这些行删除:
df1[~df1.isin(df2)].dropna()
需要注意的是,如果第二个数据框的行不是按照相同的方式开始的,则第二种方法不适用。例如,如果`df2`的行不是按顺序开始的,那么第二种方法会返回整个`df1`:
df2 = pd.DataFrame(data = {'col1' : [2, 3,4], 'col2' : [11, 12,13]}) df1[~df1.isin(df2)].dropna()
在这种情况下,可以使用`df1[~df1.isin(df2)].dropna(how='all')`来解决这个问题。
关于代码中的`~`符号的解释:`~`符号表示对表达式取反,即选择不在表达式中的值。
另外,还有一种更简洁的解决方法:`df1[~df1.index.isin(df2.index)]`。
问题:如何获取第一个数据框中不存在于第二个数据框中的记录?
原因:目前选定的解决方案产生了错误的结果。为了正确解决这个问题,我们可以从df1左连接到df2,确保先获取df2的唯一行。
解决方法:
首先,我们需要修改原始数据框,添加包含数据[3, 10]的行。
import pandas as pd df1 = pd.DataFrame(data = {'col1' : [1, 2, 3, 4, 5, 3], 'col2' : [10, 11, 12, 13, 14, 10]}) df2 = pd.DataFrame(data = {'col1' : [1, 2, 3], 'col2' : [10, 11, 12]}) df1 col1 col2 0 1 10 1 2 11 2 3 12 3 4 13 4 5 14 5 3 10 df2 col1 col2 0 1 10 1 2 11 2 3 12
进行左连接操作,消除df2中的重复行,确保df1的每一行与df2的一行进行连接。使用参数indicator返回一个额外的列,指示该行来自哪个表。
df_all = df1.merge(df2.drop_duplicates(), on=['col1','col2'], how='left', indicator=True) df_all col1 col2 _merge 0 1 10 both 1 2 11 both 2 3 12 both 3 4 13 left_only 4 5 14 left_only 5 3 10 left_only
创建一个布尔条件:
df_all['_merge'] == 'left_only' 0 False 1 False 2 False 3 True 4 True 5 True Name: _merge, dtype: bool
为什么其他解决方案是错误的:
一些解决方案犯了同样的错误-它们只检查每个列中的每个值是否独立存在,而不是在同一行中。添加最后一行,该行是唯一的,但具有来自df2的两列的值,暴露了这个错误。
common = df1.merge(df2,on=['col1','col2']) (~df1.col1.isin(common.col1))&(~df1.col2.isin(common.col2)) 0 False 1 False 2 False 3 True 4 True 5 False dtype: bool
这个解决方案得到了相同的错误结果:
df1.isin(df2.to_dict('l')).all(1)
但是,我想,他们假设col1是唯一的索引(问题中没有提到,但是显而易见)。所以,如果从来没有这样一种情况,即同一个col1值对应两个col2值(不能有两个col1=3的行),上面的答案是正确的。
这显然并不明显,所以你的观点是无效的。我的解决方案是泛化到更多情况。
问题,创建一个切片而不是布尔数组是否更容易?因为目标是获取行。
使用df_all[df_all['_merge'] == 'left_only']来获取结果的数据框。
对于新来的人来说,添加没有解释的额外行会引起困惑。然后,使这个解决方案更好。此外,我建议使用how='outer',这样_merge列就会有left/right/both,当未来的读者试图将解决方案应用到他们的问题时,更容易理解。
是否可能获取"left-only"的计数?
为什么需要.drop_duplicates()?我没有看到DF中有任何重复行。