Estoy usando chispa con python. Después de cargar un archivo csv, necesitaba analizar una columna en un archivo csv que tiene números que tienen 22 dígitos de longitud. Para analizar esa columna utilicé LongType () . Utilicé la función map () para definir la columna. Los siguientes son mis comandos en pyspark.
>>> test=sc.textFile("test.csv") >>> header=test.first() >>> schemaString = header.replace('"','') >>> testfields = [StructField(field_name, StringType(), True) for field_name in schemaString.split(',')] >>> testfields[5].dataType = LongType() >>> testschema = StructType(testfields) >>> testHeader = test.filter(lambda l: "test_date" in l) >>> testNoHeader = test.subtract(testHeader) >>> test_temp = testNoHeader.map(lambda k: k.split(",")).map(lambda p:(p[0],p[1],p[2],p[3],p[4],***float(p[5].strip('"'))***,p[6],p[7])) >>> test_temp.top(2)
Nota: También he intentado ‘long’ y ‘bigint’ en lugar de ‘float’ en mi variable test_temp , pero el error en la chispa fue ‘palabra clave no encontrada’ y a continuación se muestra la salida
[('2012-03-14', '7', '1698.00', 'XYZ02abc008793060653', 'II93', ***8.27370028700801e+21*** , 'W0W0000000000007', '879870080088815007'), ('2002-03-14', '1', '999.00', 'ABC02E000050086941', 'II93', 8.37670028702205e+21, 'A0B0080000012523', '870870080000012421')]
El valor en mi archivo CSV es el siguiente: 8.27370028700801e + 21 es 8273700287008010012345 8.37670028702205e + 21 es 8376700287022050054321
Cuando creo un dataframe fuera de él y luego lo pregunto,
>>> test_df = sqlContext.createDataFrame(test_temp, testschema) >>> test_df.registerTempTable("test") >>> sqlContext.sql("SELECT test_column FROM test").show()
el test_column
da valor ‘nulo’ para todos los registros.
Entonces, cómo resolver este problema de analizar un gran número en chispa, realmente aprecio su ayuda
Bueno, los tipos importan. Como convierte sus datos a float
no puede usar LongType
en el DataFrame
. No funciona solo porque PySpark es relativamente indulgente cuando se trata de tipos.
Además, 8273700287008010012345
es 8273700287008010012345
grande para representarlo como LontType
que puede representar solo los valores entre -9223372036854775808 y 9223372036854775807.
Si desea que sus datos se DataFrame
un DataFrame
, tendrá que usar DoubleType
:
from pyspark.sql.types import * rdd = sc.parallelize([(8.27370028700801e+21, )]) schema = StructType([StructField("x", DoubleType(), False)]) rdd.toDF(schema).show() ## +-------------------+ ## | x| ## +-------------------+ ## |8.27370028700801E21| ## +-------------------+
Por lo general, es una mejor idea manejar esto con DataFrames
directamente:
from pyspark.sql.functions import col str_df = sc.parallelize([("8273700287008010012345", )]).toDF(["x"]) str_df.select(col("x").cast("double")).show() ## +-------------------+ ## | x| ## +-------------------+ ## |8.27370028700801E21| ## +-------------------+
Si no desea utilizar el Double
, puede convertir a Decimal
con la precisión especificada:
str_df.select(col("x").cast(DecimalType(38))).show(1, False) ## +----------------------+ ## |x | ## +----------------------+ ## |8273700287008010012345| ## +----------------------+