Pandas将所有行列在一个数据帧中但不包含其他UNORDERD

时间:2016-08-30 21:51:27

标签: python python-3.x pandas dataframe

如果数据是无序的,我找不到一种简单的方法来获取在一个数据帧中找到的数据帧的所有行,但不能找到第二个数据帧。

这两个答案是有序数据的解决方案:

  

Get rows that are present in one dataframe, but not the other

     

pandas get rows which are NOT in other dataframe

所以只是为了说清楚我想要得到这个: data from one dataframe thats not found in the other dataframe

在上面提到的一个相关问题中,我发现了一个多索引解决方案,据说可以使用无序数据,但我无法实现它。我希望这是一个更简单的方法。

让我举一个我正在使用的数据的例子:

DF1
col_a   col_b
1325    foo
1397    foo        #<---matching value, but not matching index in DF2
1645    foo
...     ...

DF2
col_1   col_2
1397    foo        #<---matching value, but not matching index in DF1
1500    foo
1621    foo
...     ...

现在,如果这是两个数据帧中的所有数据,那么专门为DF1处理的结果将如下所示:

DF1_UNIQUE
col_a   col_b
1325    foo
1645    foo

(所以我真的只关心col_a或DF2 col_1)。注意它错过了1397行。那是因为它在DF2中找到,所以我不希望它返回到我的新DF。但它没有在同一个索引中找到并存在我的问题。如果所有匹配的索引都排成一行,我已经很容易创建了一个解决方案,但我不知道从哪里开始排列的索引。我可以使用合并功能吗?或者这是这项工作的错误工具?

这段代码并不完全相关,但是如果所有索引都正确排列,我会提出解决方案:

def getUniqueEntries(df1, df2):
    """takes two dataframes, returns a dataframe that is comprized of all the rows unique to the first dataframe."""
    d1columns = df1.columns
    d2columns = df2.columns
    df3 = pd.merge(df1, df2, left_on=d1columns[0], right_on=d2columns[0])
    print(df3)
    return df1[(~df1[d1columns[0]].isin(df3[d1columns[0]]))]     

def main(fileread1, fileread2, writeprefix):
    df1 = pd.read_csv(fileread1)
    df2 = pd.read_csv(fileread2)

    df3 = getUniqueEntries(df1, df2)
    df4 = getUniqueEntries(df2, df1)

    print(df3)
    print(df4)

    df3.to_csv(writeprefix+fileread1, index=False)
    df4.to_csv(writeprefix+fileread2, index=False)

if __name__ == '__main__':
    main(sys.argv[1], sys.argv[2], sys.argv[3])

3 个答案:

答案 0 :(得分:4)

是的,您可以使用indicator参数合并:

我重命名了列以避免重复列您还可以传递left_onright_on

merged = DF1.merge(DF2.rename(columns={'col_1': 'col_a', 'col_2': 'col_b'}), how='left', indicator=True)
merged
Out: 
   col_a col_b     _merge
0   1325   foo  left_only
1   1397   foo       both
2   1645   foo  left_only

现在,您可以使用指标列过滤merged

merged[merged['_merge']=='left_only']
Out: 
   col_a col_b     _merge
0   1325   foo  left_only
2   1645   foo  left_only

答案 1 :(得分:3)

这使用布尔索引来查找df1col_a~col_adf2中的值不是~的所有行。它使用isin()来查找匹配的行,使用否定运算符(df1[~df1.col_a.isin(df2.col_a)] )来查找相反的行(即那些不匹配的行)。

col_a

您提到了一个索引,但您的示例数据没有索引。因此,匹配仅根据您的示例class Component1 extends React.Component { constructor(...props) { super(...props) this.update = this.update.bind(this) this.state = { count: 0 } } update (storeData) { this.setState(storeData) } componentDidMount () { store.subscribe(this.update) } componentDidUnmount () { store.unsubscribe(this.update) } render () { return (<span>You have clicked {this.state.count} times</span>) } } 中的值进行。

答案 2 :(得分:3)

这是一个与SQL相同的pandas(Oracle&#39; s)减去操作:

select col1, col2 from tab1
minus
select col1, col2 from tab2
在Pandas中

In [59]: df1[~df1.isin(pd.DataFrame(df2.values, columns=df1.columns).to_dict('l')).all(1)]
Out[59]:
   col_a col_b
0   1325   foo
2   1645   foo

说明:

In [60]: pd.DataFrame(df2.values, columns=df1.columns)
Out[60]:
  col_a col_b
0  1397   foo
1  1500   foo
2  1621   foo

In [61]: pd.DataFrame(df2.values, columns=df1.columns).to_dict('l')
Out[61]: {'col_a': [1397, 1500, 1621], 'col_b': ['foo', 'foo', 'foo']}

In [62]: df1.isin(pd.DataFrame(df2.values, columns=df1.columns).to_dict('l'))
Out[62]:
   col_a col_b
0  False  True
1   True  True
2  False  True

In [63]: df1.isin(pd.DataFrame(df2.values, columns=df1.columns).to_dict('l')).all(1)
Out[63]:
0    False
1     True
2    False
dtype: bool