2016-07-21 3 views
1

У меня есть Dataframe df, который имеет, среди прочих, столбец groupID; то есть каждое наблюдение относится к определенной группе. Всего 8 групп. Я хотел бы пробовать от каждого groupID определенный процент наблюдений (скажем, 20%). Вот мой подход делает это:Для цикла Spark dataframe

val sample_df = for (i <- Array.range(0,7)) yield { 
      val sel_df = df.filter($"groupID"===i) 
      sel_df.sample(false,0.2,seed1) 
      } 

Результат этого кода:

Array[org.apache.spark.sql.DataFrame] = Array([text: string, groupID: int], [text: string, groupID: int]) 

Я применил flatMap() на sample_df, но я получил сообщение об ошибке:

val flat_df = sample_df.flatMap(x => x) 
     <console>:59: error: type mismatch; 
     found: org.apache.spark.sql.DataFrame 
     required: scala.collection.GenTraversableOnce[?] 

Как может Я получаю выборочный кадр данных?

ответ

1

Я думаю, вас хочет образец равномерно по каждой группе.

sample_df.reduceLeft((result, df) => result.unionAll(df)) 
+0

Отлично! Это решает! – aigujin

2

Насколько я понял, вы пытаетесь получить RDD из Row. Для этого вы можете просто позвонить:

val rows: RDD[Row] = sample_df.rdd 

Чтобы объяснить ошибку вы получите лучше, flatMap требует чего-то проходимого как Option но поставляется только с Row.

Кроме того, чтобы получить все данные водителя, вы можете позвонить:

val rows: Array[Row] = sample_df.collect 
+1

Привет, спасибо за ответ , К сожалению, 'sample_df' представляет собой массив массивов данных (' org.apache.spark.sql.DataFrame') и '.rdd' метод не работает на них. Мне нужно, чтобы эта массивная коллекция была только для dataframe. Вот почему я применил «flatMap» в первую очередь. – aigujin

+0

Правильно, извините. Тогда ответ Роки Янга правильный. –

0

Мне кажется, вы просто хотите взять 20% образец всего кадра данных? Если это так, то нет причин создавать 8 разных фреймов данных, а затем объединять их.

df.sample(false, 0.2, seed)

будет делать трюк. Если вы хотите сделать разные фракции для каждого идентификатора группы, то проверьте df.stat.sampleBy. Если вы хотите быть уверены, что есть точно 20% от каждого класса в образце, то вам придется конвертировать в PairRDD и использовать стратифицированную выборку, как:

df.rdd.map(row => (row(groupIDIndex), row)).sampleByKeyExact(false, Map(0 -> 0.2, 1 -> 0.2, ..., 8 -> 0.2), seed)