Python 在公共列之间使用逻辑or合并两个数据帧

Python 在公共列之间使用逻辑or合并两个数据帧,python,pandas,Python,Pandas,我有两个熊猫数据帧A和B,用日期索引: >>> A a b c Timestamp 2018-02-19 True False False 2018-02-20 False True False 2018-02-21 False False True 及 我希望合并这两个数据帧,以便合并的数据帧是每个公共条目(索引、列)之间的逻辑或,还包括每个数据帧唯一的列。在这种情况下,输出为: >>&

我有两个熊猫数据帧
A
B
,用日期索引:

>>> A
                a      b      c
Timestamp
2018-02-19   True  False  False
2018-02-20  False   True  False
2018-02-21  False  False   True

我希望合并这两个数据帧,以便合并的数据帧是每个公共条目(索引、列)之间的逻辑
,还包括每个数据帧唯一的列。在这种情况下,输出为:

>>> C
                a      b      c      d
Timestamp
2018-02-19   True   True  False   True
2018-02-20  False   True  False  False
2018-02-21   True   True   True   True

有没有办法在熊猫身上做到这一点?

可能有一个更优雅、更具普遍性的解决方案,但这将适用于您给出的简单示例

A = pd.DataFrame({"a":[True, False, False],
                  'b':[False, True, False],
                  'c': [False, False, True]},
                  index=['a','b','c'])

B = pd.DataFrame({"a":[False, False, True],
                  'b':[True, False, True], 
                  'd': [True, False, True]}, 
                  index=['a','b','c'])

C = pd.concat([(A | B)[['a', 'b']], A['c'], B['d']], axis=1)

print C

       a     b      c      d
a   True  True  False   True
b  False  True  False  False
c   True  True   True   True
这将对两个帧进行排序,这将为公共列(a、b)生成正确的结果,但为c、d列生成Nan。因此,我们只需将a列和b列切掉,然后与c列和d列连接,因为OR操作保持不变

编辑:根据您的评论,这里有一个更通用的解决方案,它将使您不必知道和/或硬编码特定的列名

# Get all column names
all_columns = A.columns | B.columns

# Get column names in common
union = A.columns & B.columns

# Get disjoint column names
not_B = list(set(all_columns) - set(B.columns))
not_A = list(set(all_columns) - set(A.columns))

# Logical-or common columns, and concatenate disjoint columns
C = pd.concat([A[union] | B[union], A[not_B], B[not_A]], axis=1)

# If columns names get disordered because of set operations, use
# `all_columns` to reorder

print(C[all_columns])

       a     b      c      d
a   True  True  False   True
b  False  True  False  False
c   True  True   True   True
编辑2:Per的最终解决方案,这里是一个更新版本,可用于两个以上的数据帧

# For Python 3
from functools import reduce

# A third data frame
C = pd.DataFrame({'a':[False, False, False],
                  'b':[True, True, False], 
                  'e': [True, True, True]}, 
                  index=['a','b','c'])

def logical_merge(A, B):

    # Get all column names
    all_columns = A.columns | B.columns

    # Get column names in common
    common = A.columns & B.columns

    # Get disjoint column names
    _A = [x for x in B.columns if not x in common]
    _B = [x for x in A.columns if not x in common]

    # Logical-or common columns, and concatenate disjoint columns
    return pd.concat([(A | B)[common], A[_B], B[_A]], axis=1)[all_columns]

frames = [A, B, C]

print(reduce(logical_merge, frames))

       a     b      c      d     e
a   True  True  False   True  True
b  False  True  False  False  True
c   True  True   True   True  True

这绝对有帮助,谢谢!考虑到跟踪这些列是可行的,但很麻烦,我仍然想知道是否有一个更通用的解决方案来处理非重叠列。我想得越多,就越觉得没有一个真正灵巧的解决方案。合并或连接帧实际上不允许对数据本身进行任何算术或逻辑操作。再说一次,我可能错了。在任何情况下,我添加了一个更一般化的解决方案。希望有帮助!编辑后的解决方案效果良好。最后,我将代码(在编辑之后)放入一个函数中,然后在数据帧列表上使用reduce来概括2个以上的数据帧。作品很棒:-)虽然这不是原始问题的一部分,只是为了保持简单。非常流畅!我已为可能前来查看的其他人添加了您的解决方案。
# For Python 3
from functools import reduce

# A third data frame
C = pd.DataFrame({'a':[False, False, False],
                  'b':[True, True, False], 
                  'e': [True, True, True]}, 
                  index=['a','b','c'])

def logical_merge(A, B):

    # Get all column names
    all_columns = A.columns | B.columns

    # Get column names in common
    common = A.columns & B.columns

    # Get disjoint column names
    _A = [x for x in B.columns if not x in common]
    _B = [x for x in A.columns if not x in common]

    # Logical-or common columns, and concatenate disjoint columns
    return pd.concat([(A | B)[common], A[_B], B[_A]], axis=1)[all_columns]

frames = [A, B, C]

print(reduce(logical_merge, frames))

       a     b      c      d     e
a   True  True  False   True  True
b  False  True  False  False  True
c   True  True   True   True  True