是否有一种pythonic方法来获取数据帧之间的差异?

时间:2017-03-24 18:21:22

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

鉴于这两个数据帧:

A = pd.DataFrame([[1, 5, 2, 8, 2], [2, 4, 4, 20, 2], [3, 3, 1, 20, 2], [4, 2, 2, 1, 0], 
              [5, 1, 4, -5, -4], [1, 5, 2, 2, -20], [2, 4, 4, 3, 0], [3, 3, 1, -1, -1], 
              [4, 2, 2, 0, 0], [5, 1, 4, 20, -2]],
             columns=["A", "B", "C", "D", "E"],
             index=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

B = pd.DataFrame([[1, 5, 2, 8, 2], [2, 4, 4, 20, 2], [3, 3, 1, 20, 2], [4, 2, 2, 1, 0]],
             columns=["A", "B", "C", "D", "E"],
             index=[1, 2, 3, 4])

是否有pythonic方式获得C = A - B,输出为:

    A   B   C    D    E
5   5   1   4   -5   -4
6   1   5   2    2  -20
7   2   4   4    3    0
8   3   3   1   -1   -1
9   4   2   2    0    0
10  5   1   4   20   -2

2 个答案:

答案 0 :(得分:5)

如果索引有意义,您可以根据索引进行分组:

A[~A.index.isin(B.index)]

enter image description here

答案 1 :(得分:4)

修改已更改回答,使用基于.loc的索引而不是.ix 您可以使用索引的对称差异来索引A. pandas索引的行为也大致类似于set

In [11]: A.loc[A.index.symmetric_difference(B.index)]
Out[11]:
    A  B  C   D   E
5   5  1  4  -5  -4
6   1  5  2   2 -20
7   2  4  4   3   0
8   3  3  1  -1  -1
9   4  2  2   0   0
10  5  1  4  20  -2

或许你只想要difference,这相当于不相交情况下的对称差异:

In [17]: A.loc[A.index.difference(B.index)]
Out[17]:
    A  B  C   D   E
5   5  1  4  -5  -4
6   1  5  2   2 -20
7   2  4  4   3   0
8   3  3  1  -1  -1
9   4  2  2   0   0
10  5  1  4  20  -2

您也可以直接使用大多数重载的set运算符:

In [18]: A.loc[A.index & B.index] # intersection 
Out[18]:
   A  B  C   D  E
1  1  5  2   8  2
2  2  4  4  20  2
3  3  3  1  20  2
4  4  2  2   1  0

In [19]: A.loc[A.index | B.index] # union
Out[19]:
    A  B  C   D   E
1   1  5  2   8   2
2   2  4  4  20   2
3   3  3  1  20   2
4   4  2  2   1   0
5   5  1  4  -5  -4
6   1  5  2   2 -20
7   2  4  4   3   0
8   3  3  1  -1  -1
9   4  2  2   0   0
10  5  1  4  20  -2

In [20]: A.loc[A.index ^  B.index] # disjunctive union, i.e. symmetric difference and XOR 
Out[20]:
    A  B  C   D   E
5   5  1  4  -5  -4
6   1  5  2   2 -20
7   2  4  4   3   0
8   3  3  1  -1  -1
9   4  2  2   0   0
10  5  1  4  20  -2