我有两个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
和
>>> B
a b d
Timestamp
2018-02-19 False True True
2018-02-20 False False False
2018-02-21 True True True
我想合并这两个数据帧,使得合并的数据帧在每个公共条目(索引,列)之间是逻辑or
,并且还包括每个数据帧唯一的列。在这种情况下,输出将是:
>>> 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
有没有办法在熊猫中做到这一点?
答案 0 :(得分:2)
这可能是一个更优雅和更通用的解决方案,但这适用于您已经给出的简单示例。
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
这对两个帧进行OR运算,这将为共同的列(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 :根据kmundnic的最终解决方案,这是一个更新的版本,适用于更多的两个数据框。
# 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