我正在尝试根据字典中给出的数据对数据框中的特定列进行分箱。
以下是我使用的数据框:
df
SNo,Name,CScore 1,x,700 2,y,850 3,z,560 4,a,578 5,b,456 6,c,678
我创建了以下函数,如果我单独使用它,它可以正常工作。
def binning(column,dict): finalColumn=[] lent = len(column) for i in range(lent): for j in range(len(list(dict))): if( int(column[i]) in range(list(dict)[j][0],list(dict)[j][1])): finalColumn.append(dict[list(dict)[j]]) return finalColumn
我在下面的语句中使用了上面的功能。
newDf = df.withColumn("binnedColumn",binning(df.select("CScore").rdd.flatMap(lambda x: x).collect(),{(1,400):'Low',(401,900):'High'}))
我收到以下错误:
回溯(最近通话最近): 文件“”,第1行,位于 文件“ C:\ spark_2.4 \ python \ pyspark \ sql \ dataframe.py”,第1988行,withColumn assert isinstance(col,Column),“ col应该是列” AssertionError:col应该是Column
解决这个问题的任何帮助都会有很大帮助。谢谢。
答案 0 :(得分:0)
让我们从创建数据开始:
rdd = sc.parallelize([[1,"x",700],[2,"y",850],[3,"z",560],[4,"a",578],[5,"b",456],[6,"c",678]])
df = rdd.toDF(["SNo","Name","CScore"])
>>> df.show()
+---+----+------+
|SNo|Name|CScore|
+---+----+------+
| 1| x| 700|
| 2| y| 850|
| 3| z| 560|
| 4| a| 578|
| 5| b| 456|
| 6| c| 678|
+---+----+------+
如果您的最终目标是像您的示例一样提供binning_dictionary,则查找相应的分类值。 udf是解决方案。
以下是您的正常功能。
bin_lookup = {(1,400):'Low',(401,900):'High'}
def binning(value, lookup_dict=bin_lookup):
for key in lookup_dict.keys():
if key[0] <= value <= key[1]:
return lookup_dict[key]
注册为udf并通过数据框运行它:
from pyspark.sql.functions import udf
from pyspark.sql.types import StringType
binning_udf = udf(binning, StringType())
>>> df.withColumn("binnedColumn", binning_udf("CScore")).show()
+---+----+------+------------+
|SNo|Name|CScore|binnedColumn|
+---+----+------+------------+
| 1| x| 700| High|
| 2| y| 850| High|
| 3| z| 560| High|
| 4| a| 578| High|
| 5| b| 456| High|
| 6| c| 678| High|
+---+----+------+------------+
直接应用于rdd:
>>> rdd.map(lambda row: binning(row[-1], bin_lookup)).collect()
['High', 'High', 'High', 'High', 'High', 'High']