Использование значения столбца при приведении другого столбца в кадре данных искры - PullRequest
0 голосов
/ 28 августа 2018

У меня есть такой фрейм данных:

rdd1 = sc.parallelize([(100,2,1234.5678),(101,3,1234.5678)])
df = spark.createDataFrame(rdd1,(['id','dec','val']))

+---+---+---------+
| id|dec|      val|
+---+---+---------+
|100|  2|1234.5678|
|101|  3|1234.5678|
+---+---+---------+

Исходя из значения, доступного в столбце dec, я хочу, чтобы приведение было выполнено к столбцу val. Например, если dec = 2, тогда я хочу, чтобы val был приведен к DecimalType(7,2).

Я пытался сделать ниже, но это не работает:

 df.select(col('id'),col('dec'),col('val'),col('val').cast(DecimalType(7,col('dec'))).cast(StringType()).alias('modVal')).show()

Сообщение об ошибке:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/spark/python/pyspark/sql/column.py", line 419, in cast
    jdt = spark._jsparkSession.parseDataType(dataType.json())
  File "/usr/lib/spark/python/pyspark/sql/types.py", line 69, in json
    return json.dumps(self.jsonValue(),
  File "/usr/lib/spark/python/pyspark/sql/types.py", line 225, in jsonValue
    return "decimal(%d,%d)" % (self.precision, self.scale)
TypeError: %d format: a number is required, not Column

То же самое работает, если я жестко закодирую значение для определенного числа, что прямо.

df.select(col('id'),col('dec'),col('val'),col('val').cast(DecimalType(7,3)).cast(StringType()).alias('modVal')).show()

+---+---+---------+--------+
| id|dec|      val|  modVal|
+---+---+---------+--------+
|100|  2|1234.5678|1234.568|
|101|  3|1234.5678|1234.568|
+---+---+---------+--------+

Пожалуйста, помогите мне с этим.

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Как упомянуто пользователем10281832, в одном столбце не может быть разных типов данных.

Поскольку форматирование находится в фокусе, вы можете преобразовать столбец в строковый тип, а затем выполнить форматирование. Поскольку количество десятичных знаков для каждой строки различно, вы не можете использовать любые встроенные функции Spark, но вам нужно определить пользовательский UDF:

from pyspark.sql.functions import udf
from pyspark.sql.types import StringType

def format_val(num, prec):
    return "%0.*f" % (prec, num)

format_val_udf = udf(format_val, StringType())

df.withColumn('modVal', format_val_udf('val', 'dec'))
0 голосов
/ 28 августа 2018

Столбцы в Spark (или любой реляционной системе в этом отношении) должны быть однородными - такая операция, при которой cast каждая строка имеет различный тип, не только не поддерживается, но и не имеет особого смысла.

...