@pandas_udf(StringType())
def convert_num(y):
try:
if y.endswith('K')==True:
y = list(y)
y.remove(y[''.join(y).find('K')])
if ''.join(y).startswith('€')==True:
y.remove(y[''.join(y).find('€')])
else:
pass
try :
return str(int(''.join(y))*1000)
except:
return y
elif y.endswith('M')==True:
y = list(y)
y.remove(y[''.join(y).find('M')])
if ''.join(y).startswith('€')==True:
y = list(y)
y.remove(y[''.join(y).find('€')])
else:
pass
try :
return str(float(''.join(y))*1000000)
except:
return y
except:
return y
字符串
我把上面的UDF作为pandas UDF。
在我的spark框架中有一个名为Value
的列。我想应用这个函数并转换它。
我用这个
from pyspark.sql.functions import *
df.select(convert_num(df.Value).alias('converted')).take(5)
型
但是它返回给我的是相同的值,而不是转换它。你可以在下面看到结果。
Row(Player_name='T. Almada', Images='https://cdn.sofifa.net/players/245/371/24_60.png', Age=22, National_team='Argentina', Positions="['CAM', 'CM', 'CF']", Overall=79, Potential_overall=87, Current_club='Atlanta United', Current_contract='2022 ~ 2025', **Value='€39.5M'**, Wage='€10K', Total_stats=2050, **converted_amount='€39.5M'**)
型
我哪里做错了。
2条答案
按热度按时间gwbalxhn1#
问题是
@pandas_udf
装饰器意味着convert_num(y)
期望y
是Series
,但您将y视为字符串。同样从调试的Angular 来看,在
except
块中返回y
的多个try/except块将很难确定一个或多个try块中任何错误代码的来源(如果你得到相同的列值,那么在某个地方抛出了异常,但是从哪个except块?)。请注意,如果删除外部try/except块,那么运行
df.select(convert_num(df.Value)).take(5)
将抛出:字符串
你可以通过重新构造你的convert_num函数来解决这个问题,将输入y视为Series,并在仍然使用相同的字符串逻辑的情况下输出Series:
型
PySpark DataFrame
df
示例:型
转换
Value
列后输出df
:型
bsxbgnwa2#
正如有人在评论中问到的,如何在不使用
pandas
的情况下在spark
中实现自定义转换,这里有一个简单的例子:字符串
请注意
@udf
装饰器,它接受一个值并返回转换后的值,该值将成为框架的一部分。注意:spark优化器通常很难优化udf中的代码。
参考文献:1 2