Estoy trabajando en Databricks.
Tengo un marco de datos que contiene 500 filas, me gustaría crear dos marcos de datos que contengan 100 filas y el otro que contenga las 400 filas restantes.
+--------------------+----------+ | userid| eventdate| +--------------------+----------+ |00518b128fc9459d9...|2017-10-09| |00976c0b7f2c4c2ca...|2017-12-16| |00a60fb81aa74f35a...|2017-12-04| |00f9f7234e2c4bf78...|2017-05-09| |0146fe6ad7a243c3b...|2017-11-21| |016567f169c145ddb...|2017-10-16| |01ccd278777946cb8...|2017-07-05|He intentado lo siguiente pero recibo un error.
df1 = df[:99] df2 = df[100:499] TypeError: unexpected item type: <type 'slice'>Inicialmente no entendí bien y pensé que querías cortar las columnas. Si desea seleccionar un subconjunto de filas, un método es crear una columna de índice utilizando monotonically_increasing_id() . De los documentos:
Se garantiza que el ID generado será monotónicamente creciente y único, pero no consecutivo.
Puede usar este ID para ordenar el marco de datos y crear subconjuntos usando limit() para asegurarse de obtener exactamente las filas que desea.
Por ejemplo:
import pyspark.sql.functions as f import string # create a dummy df with 500 rows and 2 columns N = 500 numbers = [i%26 for i in range(N)] letters = [string.ascii_uppercase[n] for n in numbers] df = sqlCtx.createDataFrame( zip(numbers, letters), ('numbers', 'letters') ) # add an index column df = df.withColumn('index', f.monotonically_increasing_id()) # sort ascending and take first 100 rows for df1 df1 = df.sort('index').limit(100) # sort descending and take 400 rows for df2 df2 = df.sort('index', ascending=False).limit(400)Solo para verificar que esto hizo lo que querías:
df1.count() #100 df2.count() #400También podemos verificar que la columna de índice no se superponga:
df1.select(f.min('index').alias('min'), f.max('index').alias('max')).show() #+---+---+ #|min|max| #+---+---+ #| 0| 99| #+---+---+ df2.select(f.min('index').alias('min'), f.max('index').alias('max')).show() #+---+----------+ #|min| max| #+---+----------+ #|100|8589934841| #+---+----------+Los marcos de datos de Spark no se pueden indexar como usted escribe. Puede usar el método head para crear para tomar las n filas superiores. Esto devolverá una lista de objetos Row() y no un marco de datos. Por lo tanto, puede volver a convertirlos en marco de datos y usar la resta del marco de datos original para tomar el resto de las filas.
#Take the 100 top rows convert them to dataframe #Also you need to provide the schema also to avoid errors df1 = sqlContext.createDataFrame(df.head(100), df.schema) #Take the rest of the rows df2 = df.subtract(df1)También puede usar SparkSession en lugar de spark sqlContext si trabaja en spark 2.0+. Además, si no está interesado en tomar las primeras 100 filas y desea una división aleatoria, puede usar randomSplit de esta manera:
df1,df2 = df.randomSplit([0.20, 0.80],seed=1234)Si no me importa tener las mismas filas en ambos marcos de datos, puedo usar sample . Por ejemplo, tengo un marco de datos con 354 filas.
>>> df.count() 354 >>> df.sample(False,0.5,0).count() //approx. 50% 179 >>> df.sample(False,0.1,0).count() //approx. 10% 34Alternativamente, si quiero dividir estrictamente sin duplicados presentes, podría hacer
df1 = df.limit(100) //100 rows df2 = df.subtract(df1) //Remaining rows