我有两个 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
我想合并这两个数据框,以便合并后的数据框是每个公共(public)条目(索引、列)之间的逻辑或
,并且还包括每个数据框唯一的列。在这种情况下,输出将是:
>>> 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
有没有办法在 pandas 中做到这一点?
最佳答案
可能有一个更优雅和更通用的解决方案,但这适用于您给出的简单示例。
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
这对两个帧进行“或”运算,这将为公共(public)列 (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
关于python - Pandas 使用逻辑或公共(public)列之间的方式合并两个数据框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50478011/