python - Pandas 使用逻辑或公共(public)列之间的方式合并两个数据框

标签 python pandas

我有两个 pandas 数据框 AB,用日期索引:

>>> 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/

相关文章:

python - 使用 Pandas 数据框按日期和小时对数据进行分组

python - 在类变量中创建对类的引用并在 __init__ 中实例化它们

python - 如何用趋势线绘制多条轨迹?

python - 如何在 Python 用户定义函数中使用数组/向量?

python列表列表索引

python - 这是一个错误还是我不明白什么?

python - 在使用 pd.pivot_table 制作的散点图中为每个类设置不同的颜色

python - Pandas 在具有多种数据类型的系列中崩溃

python - mplayer.py 在交互式 python shell 中工作正常,但在脚本中不工作

python - 将列值添加到后续行,直到出现新的列值