将一个 Pandas DataFrame 的副本合并到另一个 DataFrame 的每一行中?

tee*_*pee 5 python merge dataframe python-3.x pandas

我有一个场景,我想通过将另一个较小的表合并到数据帧的每一行来扩展数据帧。

换句话说,如果较大的表是 10 行,而小表是 2 行,那么结果将是一个长度为 20 的表,其中原始表中的每一行都被复制,并且较小表中的新列被合并。

为了实现这一点,我编写了一个小函数,将一个公共列添加到每个表中,合并该列,然后删除该列。

def merge_expand(big, small):
    placeholder = "__placeholderstring__"
    big.insert(0, placeholder, 1)
    small.insert(0, placeholder, 1)
    merged = big.merge(small, how='left', on=placeholder)
    merged.drop(columns=placeholder, inplace=True)
    return merged

# example
big = pd.DataFrame({'a': [1,2,3], 'b': [4,5,6]})
small = pd.DataFrame({'id': ['aa','bb'], 'val':['a','b']})
merge_expand(big, small)

# output:
   a  b  id val
0  1  4  aa   a
1  1  4  bb   b
2  2  5  aa   a
3  2  5  bb   b
4  3  6  aa   a
5  3  6  bb   b
Run Code Online (Sandbox Code Playgroud)

这可以完成工作,但在我看来它很笨拙,可能不是最有效的解决方案,因为它需要执行多个 DataFrame 操作。处理这个问题的最有效方法是什么?

cal*_*ini 6

看起来您正在寻找完全连接/笛卡尔连接。pd.merge如果我们将相同的key值分配给所有观察值,则可以实现。

big.assign(key=1).merge(small.assign(key=1), how='outer', on='key')
Run Code Online (Sandbox Code Playgroud)

输出

   a  b  key  id val
0  1  4    1  aa   a
1  1  4    1  bb   b
2  2  5    1  aa   a
3  2  5    1  bb   b
4  3  6    1  aa   a
5  3  6    1  bb   b
Run Code Online (Sandbox Code Playgroud)

如果您已经有一个名为“key”的列,您基本上可以将其命名为任何内容:

big['thiswontmatchanything'] = 1
small['thiswontmatchanything'] = 1

big.merge(small, how='outer', on='thiswontmatchanything').drop('thiswontmatchanything', axis=1)
Run Code Online (Sandbox Code Playgroud)

输出

    a   b   id  val
0   1   4   aa  a
1   1   4   bb  b
2   2   5   aa  a
3   2   5   bb  b
4   3   6   aa  a
5   3   6   bb  b
Run Code Online (Sandbox Code Playgroud)


小智 6

我相信还有更短的方法。给定数据框 df1 和 df2,你可以这样做

df = df1.merge(df2, how='cross')
Run Code Online (Sandbox Code Playgroud)

或者

df = df2.merge(df1, how='cross')
Run Code Online (Sandbox Code Playgroud)

您可以实现一个简单的 if-then-else 来确定哪个数据框更小或更大。但这不包括合并操作。

  • 这是目前最好的解决方案。自 1.2.0(2020 年 12 月)以来,它仅出现在 Pandas 中。 (2认同)