将两个数据帧与一些公共列合并,其中公共列的组合需要是自定义函数

Toa*_*ady 5 python merge concat pandas

我的问题与Merge pandas 数据框非常相似,具有列操作,但它不能满足我的需求。

假设我有两个数据框,例如(请注意,数据框内容可以是浮点数而不是布尔值):

left = pd.DataFrame({0: [True, True, False], 0.5: [False, True, True]}, index=[12.5, 14, 15.5])
right = pd.DataFrame({0.7: [True, False, False], 0.5: [True, False, True]}, index=[12.5, 14, 15.5])
Run Code Online (Sandbox Code Playgroud)

        0.5    0.7
12.5   True   True
14.0  False  False
15.5   True  False
Run Code Online (Sandbox Code Playgroud)

剩下

        0.0    0.5
12.5   True  False
14.0   True   True
15.5  False   True
Run Code Online (Sandbox Code Playgroud)

如您所见,它们具有相同的索引,并且其中一列是通用的。在现实生活中,可能会有更常见的列,例如 1.0 或其他尚未定义的数字,并且每一侧都有更多独特的列。我需要组合两个数据帧,以便保留所有唯一列,并使用特定函数组合公共列,例如本示例的布尔 OR,而两个数据帧的索引始终相同。

所以结果应该是:

结果

        0.0   0.5    0.7
12.5   True  True   True
14.0   True  True  False
15.5  False  True  False
Run Code Online (Sandbox Code Playgroud)

在现实生活中,需要组合的数据帧不止两个,但它们可以一个接一个地依次组合成一个空的第一个数据帧。

我觉得 pandas.combine 可能会成功,但我无法从文档中弄清楚。任何人都会对如何通过一个或多个步骤进行操作提出建议。

ALo*_*llz 4

您可以连接数据帧,然后对列名称进行分组,以对类似名称的列应用操作:在这种情况下,您可以不用求和,然后类型转换回 bool 来获取操作or

import pandas as pd

df = pd.concat([left, right], 1)
df.groupby(df.columns, 1).sum().astype(bool)
Run Code Online (Sandbox Code Playgroud)

输出:

        0.0   0.5    0.7
12.5   True  True   True
14.0   True  True  False
15.5  False  True  False
Run Code Online (Sandbox Code Playgroud)

如果您需要了解如何以不太具体的方式执行此操作,那么只需按列分组并将某些内容应用于分组对象即可axis=1

df = pd.concat([left, right], 1)
df.groupby(df.columns, 1).apply(lambda x: x.any(1))
#        0.0   0.5    0.7
#12.5   True  True   True
#14.0   True  True  False
#15.5  False  True  False
Run Code Online (Sandbox Code Playgroud)

此外,您可以定义自定义组合功能。这是将左侧框架的两倍与右侧框架的 4 倍相加的示例。如果只有一列,则返回左帧的 2 倍。

样本数据

左边:

      0.0  0.5
12.5    1   11
14.0    2   17
15.5    3   17
Run Code Online (Sandbox Code Playgroud)

正确的:

      0.7  0.5
12.5    4    2
14.0    4   -1
15.5    5    5
Run Code Online (Sandbox Code Playgroud)

代码

def my_func(x):
    try:
        res = x.iloc[:, 0]*2 + x.iloc[:, 1]*4
    except IndexError:
        res = x.iloc[:, 0]*2
    return res

df = pd.concat([left, right], 1)
df.groupby(df.columns, 1).apply(lambda x: my_func(x))
Run Code Online (Sandbox Code Playgroud)

输出:

      0.0  0.5  0.7
12.5    2   30    8
14.0    4   30    8
15.5    6   54   10
Run Code Online (Sandbox Code Playgroud)

最后,如果您想以连续的方式执行此操作,那么您应该使用reduce. 这里我将 5DataFrames与上面的函数结合起来。(我将仅重复右侧的帧 4x 作为示例)

from functools import reduce

def my_comb(df_l, df_r, func):
    """ Concatenate df_l and df_r along axis=1. Apply the
    specified function.
    """
    df = pd.concat([df_l, df_r], 1)
    return df.groupby(df.columns, 1).apply(lambda x: func(x))

reduce(lambda dfl, dfr: my_comb(dfl, dfr, func=my_func), [left, right, right, right, right])
#      0.0  0.5  0.7
#12.5   16  296  176
#14.0   32  212  176
#15.5   48  572  220
Run Code Online (Sandbox Code Playgroud)