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
和
>>> 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
有没有办法在熊猫中做到这一点?
解决方案
可能有一个更优雅和通用的解决方案,但这适用于您给出的简单示例。
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 产生正确的结果。因此,我们只需切掉 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
推荐阅读
- ios - 使 UIScrollView 中的 UITextView 右对齐
- python - 将具有字符串列、数组列的表转换为所有字符串列
- django - ModuleNotFoundError:没有名为“allauth”的模块
- javascript - PNG作为谷歌地图上的KML层重叠一切
- gdb - 有没有办法用 GDB 实时监控数据?
- python - 烧瓶错误:AttributeError:'NoneType'对象没有属性'get'
- knime - 在 Knime 的 Python 脚本节点上运行 Python 代码
- angular - 为什么事件监听器调用子组件的 *ngIf 方法?
- javascript - 使用 Map 实例按属性名称返回不同对象的数组?
- java - 我有一个问题,它是通过 java 中的比较器的两个字段进行排序的