cómo cambiar una columna de marco de datos de tipo de cadena a tipo doble en pyspark

99

Tengo un marco de datos con una columna como Cadena. Quería cambiar el tipo de columna a tipo doble en PySpark.

A continuación se muestra la forma que hice:

toDoublefunc = UserDefinedFunction(lambda x: x,DoubleType())
changedTypedf = joindf.withColumn("label",toDoublefunc(joindf['show']))

Solo quería saber si esta es la manera correcta de hacerlo, ya que mientras ejecuto Regresión logística, recibo un error, así que me pregunto si esta es la razón del problema.

Abhishek Choudhary
fuente

Respuestas:

171

No es necesario un UDF aquí. Columnya proporciona un castmétodo con instancia :DataType

from pyspark.sql.types import DoubleType

changedTypedf = joindf.withColumn("label", joindf["show"].cast(DoubleType()))

o cuerda corta:

changedTypedf = joindf.withColumn("label", joindf["show"].cast("double"))

donde los nombres de cadenas canónicos (también se pueden admitir otras variaciones) corresponden al simpleStringvalor. Entonces, para los tipos atómicos:

from pyspark.sql import types 

for t in ['BinaryType', 'BooleanType', 'ByteType', 'DateType', 
          'DecimalType', 'DoubleType', 'FloatType', 'IntegerType', 
           'LongType', 'ShortType', 'StringType', 'TimestampType']:
    print(f"{t}: {getattr(types, t)().simpleString()}")
BinaryType: binary
BooleanType: boolean
ByteType: tinyint
DateType: date
DecimalType: decimal(10,0)
DoubleType: double
FloatType: float
IntegerType: int
LongType: bigint
ShortType: smallint
StringType: string
TimestampType: timestamp

y por ejemplo tipos complejos

types.ArrayType(types.IntegerType()).simpleString()   
'array<int>'
types.MapType(types.StringType(), types.IntegerType()).simpleString()
'map<string,int>'
zero323
fuente
2
El uso de la colfunción también funciona. from pyspark.sql.functions import col, changedTypedf = joindf.withColumn("label", col("show").cast(DoubleType()))
Staza
¿Cuáles son los valores posibles del argumento cast () (la sintaxis de "cadena")?
Wirawan Purwanto
No puedo creer lo conciso que era el documento Spark en la cadena válida para el tipo de datos. La referencia más cercana que pude encontrar fue esta: docs.tibco.com/pub/sfire-analyst/7.7.1/doc/html/en-US/… .
Wirawan Purwanto
1
¿Cómo convertir varias columnas de una sola vez?
hui chen
¿Cómo cambio la posibilidad de nulos a falso?
pitchblack408
50

Conserve el nombre de la columna y evite la adición de columnas adicionales utilizando el mismo nombre que la columna de entrada:

changedTypedf = joindf.withColumn("show", joindf["show"].cast(DoubleType()))
Anadón
fuente
3
Gracias, estaba buscando cómo conservar el nombre de la columna original
javadba
¿Hay una lista en algún lugar de los tipos de datos de cadena corta que Spark identificará?
Alfredox
1
esta solución también funciona espléndidamente en un bucle, por ejemplofrom pyspark.sql.types import IntegerType for ftr in ftr_list: df = df.withColumn(f, df[f].cast(IntegerType()))
Quetzalcoatl
11

Las respuestas dadas son suficientes para lidiar con el problema, pero quiero compartir otra forma en la que se puede presentar la nueva versión de Spark (no estoy seguro), por lo que la respuesta dada no lo captó.

Podemos llegar a la columna en la declaración de chispa con la col("colum_name")palabra clave:

from pyspark.sql.functions import col , column
changedTypedf = joindf.withColumn("show", col("show").cast("double"))
serkan kucukbay
fuente
5

versión de pyspark:

  df = <source data>
  df.printSchema()

  from pyspark.sql.types import *

  # Change column type
  df_new = df.withColumn("myColumn", df["myColumn"].cast(IntegerType()))
  df_new.printSchema()
  df_new.select("myColumn").show()
Cristian
fuente
2

la solución fue simple -

toDoublefunc = UserDefinedFunction(lambda x: float(x),DoubleType())
changedTypedf = joindf.withColumn("label",toDoublefunc(joindf['show']))
Abhishek Choudhary
fuente