我想知道为什么熊猫赋值函数不能处理返回的列表。
例如
df = pd.DataFrame({
"id" : [1,2,3,4,5],
"val" : [10,20,30,30,40]
})
def squareMe(x):
return x**2
df = df.assign(val2 = lambda x: squareMe(x.val))
# Out > Works fine : Returns a DataFrame with squared values但如果我们返回一个列表,
def squareMe(x):
return [x**2]
df = df.assign(val2 = lambda x: squareMe(x.val))
#Out > ValueError: Length of values (1) does not match length of index (5)但是,pandas应用函数在返回列表时工作得很好
def squareMe(x):
return [x**2]
df["val2"] = df.val.apply(lambda x: squareMe(x))有没有什么特别的原因是我做错了什么?
发布于 2021-10-07 09:11:37
由于您在对squareMe的调用中引用了x.val,因此将向该函数传递一个列表(您可以通过在函数内添加一个debug语句以打印type(x)来轻松地验证这一点)。
因此,x ** 2返回一个序列(因为表达式是矢量化的),赋值工作正常。
但是当您返回[x ** 2]时,您返回的是列表中的级数,这是没有意义的,因为它看到的是一个大小为"1“的迭代器(其中的级数),并且它认为这是对大小为5的DataFrame执行列赋值的错误长度(这正是ValueError: Length of values (1) does not match length of index (5)的意思)。
与apply的不同之处在于,该函数接收一个数字,而不是一个序列。因此,您仍然返回apply接受的单个项(列表),但在技术上仍然是错误的,因为您不需要将结果包装在列表中。
附言:您可能已经理解了这一点,但您可以将其简化为df['val'] = df['x'] ** 2
发布于 2021-10-07 09:13:58
assign并不是专门用来做这件事的,它是用来将已经返回的序列指定为参数的。
**参数:kwargs : dict of {str: callable or Series}
列名是关键字。如果这些值是可调用的,则在DataFrame上计算它们并将其分配给新列。callable不能改变输入DataFrame (尽管pandas不会检查它)。如果值是不可调用的(例如,序列、标量或数组),则简单地对它们进行赋值。
执行[x ** 2]将返回一系列列表,这些列表将被视为矩阵(或数据帧),因此错误提示如下:
ValueError:值的长度(%1)与索引的长度(%5)不匹配
值的长度与索引不匹配。
https://stackoverflow.com/questions/69478364
复制相似问题