Как я могу разделить столбец от DataFrame, но сохранить его связь с начальным DataFrame? - PullRequest
0 голосов
/ 01 марта 2019

У меня есть фрейм данных dataDF, то есть:

+-------+------+-----+-----+-----------+
|TEST_PK| COL_1|COL_2|COL_3|h_timestamp|
+-------+------+-----+-----+-----------+
|      1| apple|   10| 1.79|       1111|
|      1| apple|   11| 1.79|       1114|
|      2|banana|   15| 1.79|       1112|
|      2|banana|   16| 1.79|       1115|
|      3|orange|    7| 1.79|       1113|
+-------+------+-----+-----+-----------+

И мне нужно запустить эту функцию:
operation(row, h_timestamp)
В каждой строке, но row не может содержатьh_timestamp, поэтому моя первая мысль - разделить фрейм данных следующим образом:

val columns = dataDF.drop("h_timestamp")  
val timestamp = dataDF.select("h_timestamp")  

Но это не помогает, когда я хочу выполнить операцию для каждой строки, например:

dataDF.map(row => {
  ...
  val rowWithoutTimestamp = ???
  val timestamp = ???
  operation(rowWithoutTimestamp, timestamp)
  ...
})

Но теперь эти два кадра данных не связаны, и я не знаю, как получить правильную метку времени для каждой строки.Столбец TEST_PK не обязательно является уникальным.
Есть ли способ использовать .drop() или .select() только для строки или каким-либо другим способом сделать это?
Редактировать: Кроме того, таблица может иметь любойколичество столбцов, но всегда будет иметь столбец отметки времени и, по крайней мере, еще один, который не является отметкой времени

1 Ответ

0 голосов
/ 01 марта 2019

Поскольку у вас есть то, что выглядит как столбец первичного ключа, просто вставьте временную метку со столбцом id в собственный фрейм данных, чтобы позже присоединиться к нему позже.

val tsDF = dataDF.select("TEST_PK", "h_timestamp")

Затем удалите столбец из dataDF, выполните свою операцию и снова присоедините h_timestamp обратно на новый фрейм данных.

val finalDF = postopDF.join(tsDF, "TEST_PK")

Обновление

Пример кода полезен, вам следуетвозможность по существу разбить вашу строку и перестроить новую строку с желаемыми значениями примерно так:

dataDF.map(row => {
  val rowWithoutTimestamp = Row(
    row.getAs[Long]("TEST_PK"),
    row.getAs[String]("COL_1"),
    row.getAs[Long]("COL_2"),
    row.getAs[Double]("COL_3")
  )
  val timestamp = row.getAs[Long]("h_timestamp")
  val result = operation(rowWithoutTimestamp, timestamp)
  Row(result, timestamp)
})

Конечно, я не уверен, что возвращает ваш operation(), поэтому это может быть необходиморазобрать result на отдельные значения и составить новую строку с этими значениями и отметкой времени.

Обновление 2

Хорошо, вот более общий метод.Он упаковывает «все столбцы, кроме» h_timestamp в структуру, и отображает кортеж (struct, ts).Во всяком случае, на самом деле более элегантно, чем предыдущее решение.

val cols = df.drop("h_timestamp").columns.toSeq
dataDF
  .select(struct(cols.map(c => col(c)):_*).as("row_no_ts"), $"h_timestamp")
  .map(row => {
    val rowWithoutTimestamp = row.getAs[Row]("row_no_ts")
    val timestamp = row.getAs[Long]("h_timestamp")
    operation(rowWithoutTimestamp, timestamp)
  })

Я не уверен, что вы отображаете только вывод operation() или некоторую комбинацию с меткой времени снова, но оба доступны для изменения вудовлетворить ваши потребности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...