Tengo un objeto de la serie Pandas

dates = pd.Series(pd.date_range(start_date,end_date))/
.dt.strftime('%y%m%d')/
.astype(int)/

Y me gustaría crear un Spark DF directamente desde el objeto Series, sin el marco de datos intermedio de Pandas

    _schema = StructType([
     StructField("date_id", IntegerType(), True),
])

    dates_rdd = sc.parallelize(dates)
    self.date_table = spark.createDataFrame(dates_rdd, _schema)

Error:

Error: raise TypeError("StructType can not accept object %r in type %s" % 
(obj, type(obj)))
TypeError: StructType can not accept object 160101 in type <class 
'numpy.int64'>

Si cambio el objeto Serie como:

    dates = pd.Series(pd.date_range(start_date,end_date))/
    .dt.strftime('%y%m%d')/
    .astype(int).values.tolist()

El error se convierte en:

 raise TypeError("StructType can not accept object %r in type %s" % (obj, 
 type(obj)))
 TypeError: StructType can not accept object 160101 in type <class 'int'>

¿Cómo puedo asignar correctamente los valores Int contenidos en la lista de fechas / rdd al entero nativo de Python que se acepta de Spark Dataframes?

2
balalaika 13 nov. 2017 a las 15:19

2 respuestas

La mejor respuesta

Créalo, no pudo crear una tupla para cada valor de serie,

>>> dates = pd.Series(pd.date_range(start='1/1/1980', end='1/11/1980')).dt.strftime('%y%m%d').astype(int).values.tolist()
>>> rdd = sc.parallelize(dates).map(lambda x:(x,))
>>> _schema = StructType([StructField("date_id", IntegerType(), True),])
>>> df = spark.createDataFrame(rdd,schema=_schema)
>>> df.show()
+-------+
|date_id|
+-------+
| 800101|
| 800102|
| 800103|
| 800104|
| 800105|
| 800106|
| 800107|
| 800108|
| 800109|
| 800110|
| 800111|
+-------+

>>> df.printSchema()
root
 |-- date_id: integer (nullable = true)
2
Suresh 13 nov. 2017 a las 13:32

Esto funcionará:

dates_rdd = sc.parallelize(dates).map(lambda x: tuple([int(x)]))
date_table = spark.createDataFrame(dates_rdd, _schema)

El propósito del mapa adicional al definir dates_rdd es hacer que el formato del rdd coincida con el esquema

3
ags29 13 nov. 2017 a las 13:33