熊猫版的SQL CROSS APPLY

时间:2019-04-17 10:26:55

标签: python sql pandas tsql dataframe

假设我们有一个DataFrame df

df = pd.DataFrame({
    "Id": [1, 2],
    "Value": [2, 5]
})

df
    Id  Value
0   1   2
1   2   5

和一些函数f,该函数接受df的元素并返回一个DataFrame。

def f(value):
    return pd.DataFrame({"A": range(10, 10 + value), "B": range(20, 20 + value)})

f(2)
    A   B
0   10  20
1   11  21

我们希望将f应用于df["Value"]中的每个元素,并将结果加入df中,就像这样:

    Id  Value   A   B
0   1   2       10  20
1   1   2       11  21
2   2   5       10  20
2   2   5       11  21
2   2   5       12  22
2   2   5       13  23
2   2   5       14  24

在T-SQL中,使用表df和表值函数f,我们可以使用CROSS APPLY来做到这一点:

SELECT * FROM df
CROSS APPLY f(df.Value)

我们如何在pandas中做到这一点?

2 个答案:

答案 0 :(得分:6)

您可以将该函数应用于列表理解中的it('Create new patient', function(){ Title("Mr"); Gender("M"); } 中的每个元素,并使用pd.concat连接所有结果数据帧。还要分配相应的Value,以便以后可以用于merge两个数据帧:

Id

答案 1 :(得分:2)

我会使用DataFrame.iterrows的少数情况之一。我们可以遍历每一行,将笛卡尔积与原始数据框连接起来,同时将fillnabfillffill结合起来:


df = pd.concat([pd.concat([f(r['Value']), pd.DataFrame(r).T], axis=1).bfill().ffill() for _, r in df.iterrows()], 
               ignore_index=True)

哪种产量:

print(df)
    A   B   Id  Value
0  10  20  1.0    2.0
1  11  21  1.0    2.0
2  10  20  2.0    5.0
3  11  21  2.0    5.0
4  12  22  2.0    5.0
5  13  23  2.0    5.0
6  14  24  2.0    5.0