2016-04-01 6 views
2

Ich benutze Funken mit Python.Nach dem Hochladen einer CSV-Datei, musste ich eine Spalte in einer CSV-Datei analysieren, die Zahlen hat, die 22 Ziffern lang sind. Zum Analysieren dieser Spalte habe ich LongType() verwendet. Ich benutzte map() -Funktion zum Definieren der Spalte. Im Folgenden sind meine Befehle in Pyspark.Datentyp für die Handhabung von großen Zahlen in 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) 

Anmerkung: Ich habe auch 'long' und 'bigint' anstelle von 'float' versucht, in meine Variable test_temp, aber der Fehler in Funke war 'Schlüsselwort nicht gefunden' Und finden der Ausgang

[('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')] 

der Wert in meiner cSV-Datei wird wie folgt: 8.27370028700801e + 21 ist8.37670028702205e + 21 ist

Wenn ich einen Datenrahmen aus ihm heraus erstellen und dann abfragen,

>>> test_df = sqlContext.createDataFrame(test_temp, testschema) 
>>> test_df.registerTempTable("test") 
>>> sqlContext.sql("SELECT test_column FROM test").show() 

der test_column Wert gibt 'Null' für alle Datensätze.

So, wie dieses Problem zu lösen große Zahl in Funken Parsen, wirklich zu schätzen Ihre Hilfe

Antwort

3

Nun, egal Arten. Da Sie Ihre Daten in float konvertieren, können Sie LongType in DataFrame nicht verwenden. Es weht nicht nur, weil PySpark bei Typen relativ fehlerverzeihend ist.

Auch ist 8273700287008010 zu groß ist wie LontType dargestellt werden, die nur die Werte zwischen -9223372036854775808 und 9223372036854775807.

Wenn Sie möchten, um Ihre Daten zu einem DataFrame darstellen können Sie DoubleType verwenden:

from pyspark.sql.types import * 

rdd = sc.parallelize([(8.27370028700801e+21,)]) 
schema = StructType([StructField("x", DoubleType(), False)]) 
rdd.toDF(schema).show() 

## +-------------------+ 
## |     x| 
## +-------------------+ 
## |8.27370028700801E21| 
## +-------------------+ 

Typischerweise ist es eine bessere Idee, diese direkt mit DataFrames zu handhaben:

from pyspark.sql.functions import col 

str_df = sc.parallelize([("8273700287008010",)]).toDF(["x"]) 
str_df.select(col("x").cast("double")).show() 

## +-------------------+ 
## |     x| 
## +-------------------+ 
## |8.27370028700801E21| 
## +-------------------+ 

Wenn Sie nicht über Double wollen verwenden können, um Decimal mit bestimmtem Feinguss:

str_df.select(col("x").cast(DecimalType(38))).show(1, False) 

## +----------------------+ 
## |x      | 
## +----------------------+ 
## |8273700287008010| 
## +----------------------+ 
Verwandte Themen