在python DataFrame中从lambda函数的多个返回值创建多个列

时间:2015-07-15 03:34:17

标签: python lambda dataframe

Att,我想在python DataFrame中从lambda函数的多个返回值创建多个列。

与我的演示代码的最后一行类似。

有没有办法实现这个目标?

y = np.random.rand(2,5)
df = pd.DataFrame(y, columns = ["y1", "y2", "y3", "y4", "y5"])
print(df)
def f_polyfit(y1, y2, y3, y4, y5, degree):
    y = [y1, y2, y3, y4, y5]
    x = [1, 2, 3, 4, 5]
    coeffs = np.polyfit(x, y, degree)   
    coeffs = coeffs.tolist()
    # constructe the polynomial formula
    p = np.poly1d(coeffs)
    # fit values, and mean
    y_fit = p(x)                        
    y_avg = np.sum(y)/len(y)          
    ssreg = np.sum((y_fit-y_avg)**2)   
    sstot = np.sum((y - y_avg)**2)  
    R2 = ssreg / sstot
    return coeffs[0], R2
# df["slope"], df["R2"] = zip(df.apply(lambda x:f_polyfit(x["y1"], x["y2"], x["y3"], x["y4"], x["y5"], degree = 1),  axis = 1))

3 个答案:

答案 0 :(得分:3)

一种方法是将返回值包装在pd.Series中,以便分配给新的数据帧列。

g = lambda x: pd.Series(f_polyfit(x.y1, x.y2, x.y3, x.y5, x.y5, degree=1))
df[['slope', 'R2']] = df.apply(g, axis=1)

答案 1 :(得分:0)

解决方案是理解错误消息"解包的值太多。"当Python遇到像:

这样的解包表达式时
a,b = x

迭代x并将第一个值分配给a,第二个赋值给b,等等。如果x的长度恰好为2,则该语句将无错误地执行,但如果x有三个元素,它也会引发"许多值要打开包装。"

您的最后一行代码只有在zip()函数生成的迭代器具有两个元素时才有效。显然,事实并非如此。重要的是要意识到问题与lambda或数据帧无关,而是与Python解包的基础知识有关。

答案 2 :(得分:0)

使用pd.Series的另一种方法是将输出转换为列表。然后,您可以将新列分配为:

df[['slope', 'R2']] = pd.DataFrame(df.apply(lambda x: f_polyfit(x)).tolist(), 
index=df.index)