我正在尝试在给定数据帧(dfTest,其中包含向量 x 的值)的所有行上应用基本样条函数以获得更大的函数(dfBigger),它将包含向量 xnew(其中包含 x)的所有值.
因此我定义了以下变量:
import pandas as pd
import numpy as np
x = [0,1,3,5]
xnew = range(0,6)
np.random.seed(123)
dfTest = pd.DataFrame(np.random.rand(12).reshape(3,4))
和基本样条函数:
def spline(y, x , xnew):
from scipy import interpolate
model = interpolate.splrep(x,y, s=0.)
ynew = interpolate.splev(xnew,model)
result = ynew.round(3)
return result
这似乎有效:
spline(dfTest.iloc[0],x,xnew)
Out[176]: array([ 0.696, 0.286, 0.161, 0.227, 0.388, 0.551])
但是当我尝试将它应用于所有行时:
dfBigger = dfTest.apply(lambda row : spline(row, x, xnew), axis = 1)
我明白了:
ValueError: Shape of passed values is (3, 6), indices imply (3, 4)
因为 dfBigger 大小没有在任何地方定义,所以我看不出哪里出了问题。任何有关此代码的帮助和/或评论将不胜感激。
请您参考如下方法:
df.apply(func)尝试从值中构建一个新的 Series 或 DataFrame 由 func 返回。 Series 或 DataFrame 的形状取决于 func 返回的值。为了更好地处理 df.apply 的行为, 尝试以下调用:
dfTest.apply(lambda row: 1, axis=1) # Series
dfTest.apply(lambda row: [1], axis=1) # Series
dfTest.apply(lambda row: [1,2], axis=1) # Series
dfTest.apply(lambda row: [1,2,3], axis=1) # Series
dfTest.apply(lambda row: [1,2,3,4], axis=1) # Series
dfTest.apply(lambda row: [1,2,3,4,5], axis=1) # Series
dfTest.apply(lambda row: np.array([1]), axis=1) # DataFrame
dfTest.apply(lambda row: np.array([1,2]), axis=1) # ValueError
dfTest.apply(lambda row: np.array([1,2,3]), axis=1) # ValueError
dfTest.apply(lambda row: np.array([1,2,3,4]), axis=1) # DataFrame!
dfTest.apply(lambda row: np.array([1,2,3,4,5]), axis=1) # ValueError
dfTest.apply(lambda row: pd.Series([1]), axis=1) # DataFrame
dfTest.apply(lambda row: pd.Series([1,2]), axis=1) # DataFrame
dfTest.apply(lambda row: pd.Series([1,2,3]), axis=1) # DataFrame
dfTest.apply(lambda row: pd.Series([1,2,3,4]), axis=1) # DataFrame
dfTest.apply(lambda row: pd.Series([1,2,3,4,5]), axis=1) # DataFrame
那么我们可以从这些实验中得出什么规律呢?
- 如果
func返回标量或列表,则df.apply(func)返回一个系列。 - 如果
func返回一个 Series,则df.apply(func)返回一个 DataFrame。 - 如果
func返回一维 NumPy 数组,并且该数组只有一个元素,df.apply(func)返回一个 DataFrame。 (不是一个非常有用的案例......) - 如果
func返回一维 NumPy 数组,并且该数组的元素数与df的列数相同,df .apply(func)返回一个 DataFrame。 (有用,但有限)
因为 func 返回 6 个值,而你想要一个 DataFrame 作为结果, 解决方案是让 func 返回一个 Series 而不是 NumPy 数组:
def spline(y, x, xnew):
...
return pd.Series(result)
import numpy as np
import pandas as pd
from scipy import interpolate
def spline(y, x, xnew):
model = interpolate.splrep(x,y, s=0.)
ynew = interpolate.splev(xnew,model)
result = ynew.round(3)
return pd.Series(result)
x = [0,1,3,5]
xnew = range(0,6)
np.random.seed(123)
dfTest = pd.DataFrame(np.random.rand(12).reshape(3,4))
# spline(dfTest.iloc[0],x,xnew)
dfBigger = dfTest.apply(lambda row : spline(row, x, xnew), axis=1)
print(dfBigger)
产量
0 1 2 3 4 5
0 0.696 0.286 0.161 0.227 0.388 0.551
1 0.719 0.423 0.630 0.981 1.119 0.685
2 0.481 0.392 0.333 0.343 0.462 0.729
