我在数据框中找到所有列的“MODE”并将它们存储在列表中。 计算每列的MODE的代码:
from pyspark.sql.functions import *
#calculating mode value
mode_val = []
for i in df_num.columns :
cnts = df_num.groupBy(i).count()
mode = cnts.join(
cnts.agg(max("count").alias("max_")), col("count") == col("max_")
).limit(1)
mode2 = mode.withColumn(i,col(i).cast("double"))
mode_val.append(mode2.first()[0])
[6500.0, 0.0, 没有, 1300.0, 3.0, 3.0, 0.0, 没有, 38000.0]
当我尝试将列表转换为数据帧时,我似乎遇到了错误。
这是我将MODE列表转换为dataframe的代码:
univar_df4 = spark.createDataFrame(mode_val,["Mode"])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-171-d5ca3ecf8d79> in <module>()
1 #not able to apply to dataframe.
----> 2 univar_df4 = spark.createDataFrame(mode_val,["Mode"])
/usr/lib/spark/python/pyspark/sql/session.py in createDataFrame(self, data, schema, samplingRatio, verifySchema)
535 rdd, schema = self._createFromRDD(data.map(prepare), schema, samplingRatio)
536 else:
--> 537 rdd, schema = self._createFromLocal(map(prepare, data), schema)
538 jrdd = self._jvm.SerDeUtil.toJavaArray(rdd._to_java_object_rdd())
539 jdf = self._jsparkSession.applySchemaToPythonRDD(jrdd.rdd(), schema.json())
/usr/lib/spark/python/pyspark/sql/session.py in _createFromLocal(self, data, schema)
399
400 if schema is None or isinstance(schema, (list, tuple)):
--> 401 struct = self._inferSchemaFromList(data)
402 converter = _create_converter(struct)
403 data = map(converter, data)
/usr/lib/spark/python/pyspark/sql/session.py in _inferSchemaFromList(self, data)
331 warnings.warn("inferring schema from dict is deprecated,"
332 "please use pyspark.sql.Row instead")
--> 333 schema = reduce(_merge_type, map(_infer_schema, data))
334 if _has_nulltype(schema):
335 raise ValueError("Some of types cannot be determined after inferring")
/usr/lib/spark/python/pyspark/sql/types.py in _infer_schema(row)
990
991 else:
--> 992 raise TypeError("Can not infer schema for type: %s" % type(row))
993
994 fields = [StructField(k, _infer_type(v), True) for k, v in items]
TypeError: Can not infer schema for type: <class 'float'>
答案 0 :(得分:2)
要解释该错误,我会quote myself来another question:
我认为将
createDataFrame()
的论点视为一个很有用 元组列表,其中列表中的每个条目对应于一行 DataFrame和元组的每个元素对应一列。
您可以通过使列表中的每个元素成为元组来获得所需的输出:
mode_val = [6500.0, 0.0, None, 1300.0, 3.0, 3.0, 0.0, None, 38000.0]
mode_val = [(x,) for x in mode_val]
print(mode_val)
#[(6500.0,), (0.0,), (None,), (1300.0,), (3.0,), (3.0,), (0.0,), (None,), (38000.0,)]
现在创建DataFrame:
univar_df4 = spark.createDataFrame(mode_val,["Mode"])
univar_df4.show()
#+-------+
#| Mode|
#+-------+
#| 6500.0|
#| 0.0|
#| null|
#| 1300.0|
#| 3.0|
#| 3.0|
#| 0.0|
#| null|
#|38000.0|
#+-------+
但是,似乎您的目标是将每个列的模式转换为新的DataFrame。这是一种不依赖于将值存储在列表中的替代方法:
创建一个示例DataFrame:
import pyspark.sql.functions as f
data = [
(1, 2, 3),
(1, 3, 3),
(2, 3, 2)
]
df_num = sqlCtx.createDataFrame(data, ["a", "b", "c"])
df_num.show()
#+---+---+---+
#| a| b| c|
#+---+---+---+
#| 1| 2| 3|
#| 1| 3| 3|
#| 2| 3| 2|
#+---+---+---+
使用列表理解+ reduce
和union
来获取每列的模式:
mode = reduce(
lambda a, b: a.union(b),
[
df_num.groupBy(i)\
.count()\
.sort(f.col("count").desc())\
.limit(1)\
.select(
f.lit(i).alias("col"),
f.col(i).alias("mode")
)
for i in df_num.columns
]
)
mode.show()
#+---+----+
#|col|mode|
#+---+----+
#| a| 1|
#| b| 3|
#| c| 3|
#+---+----+
在列表推导中,我们迭代DataFrame中的所有列并执行groupBy()
和count()
(正如您所做的那样)。但是,我没有查找计数等于最大值的行,而是将列降序排序并使用limit(1)
来获取最大值。
完成此步骤后,DataFrame将包含两列和一行。我们操纵值将其转换为两列的DataFrame:(column_name, mode)
。
最后,我们通过调用union来连接所有行来减少列表。