Соедините два кадра данных с scala spark - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть два кадра данных:

  • Первый кадр данных DFNum имеет 48 столбцов и 58500 строк.
  • Второй кадр данных DFString имеет 7 столбцов и 58500 строк.

Столбцы обоих фреймов данных отличаются друг от друга. Моя цель - просто объединить два фрейма данных в один, содержащий 55 столбцов (48 + 7) и всегда 58500 строк, сохраняя порядок, который они имели до объединения.

Я сделал несколько попыток, тоже читая другие вопросы, но безуспешно. В частности, я попытался:

val df = DFNum.join(DFString), и это дает мне следующую ошибку: Detected implicit cartesian product for INNER join between logical plans. Join condition is missing or trivial. Join condition is missing or trivial. Either: use the CROSS JOIN syntax to allow cartesian products between these relations, or: enable implicit cartesian products by setting the configuration variable spark.sql.crossJoin.enabled=true;.

Очевидно, что при перекрестном соединении я получаю намного больше строк, чем хочу: 58500 * 58500 строк .

Затем я попытался отредактировать df, добавив равный столбец id к обоим фреймам данных, чтобы объединить: val tmpNum = DFNum.withColumn("id", monotonically_increasing_id()) val tmpString = DFString.withColumn("id", monotonically_increasing_id())

и использовать:

val df = tmpNum.join(tmpString) и это дает мне следующую ошибку: USING column `id` cannot be resolved on the left side of the join. The left-side columns:[...].

Я также попробовал несколько типов объединений (все с tmpNum и tmpString и DFNum и DFString), например: val df = tmpNum.join(tmpString, Seq("id"), "outer") val df = tmpNum.join(tmpString, Seq("id"), "full_outer") и др. c. но я всегда получаю одну и ту же ошибку USING column `id` cannot be resolved on the left side of the join. The left-side columns:[...].

(Очевидно, с tmpNum и tmpString общее количество столбцов нового информационного кадра будет еще одним. Позже я опущу столбец id).

Если у кого-то есть идеи или предложения, я был бы признателен.

Ответы [ 3 ]

2 голосов
/ 12 февраля 2020

Если у вас нет ключевых столбцов для объединения 2-х фреймов данных, вы можете зависеть от monotonically_increasing_id

val a = Seq(("First",1), ("Secound",2), ("Third",3), ("Fourth",4)).toDF("col1", "col2")
val b = Seq(("india",980), ("japan",990), ("korea",1000), ("chaina",900)).toDF("col3", "col4")

a.show

+-------+----+
|   col1|col2|
+-------+----+
|  First|   1|
|Secound|   2|
|  Third|   3|
| Fourth|   4|
+-------+----+

b.show
+------+----+
|  col3|col4|
+------+----+
| india| 980|
| japan| 990|
| korea|1000|
|chaina| 900|
+------+----+

Затем добавьте новый столбец к обоим фреймам данных. Убедитесь, что ваш фрейм данных отсортирован правильно, иначе после объединения фреймы данных будут сбиваться.

val a1 = a.withColumn("id", monotonically_increasing_id)
val b1 = b.withColumn("id", monotonically_increasing_id)

Теперь выполните объединение обоих фреймов данных, используя столбец id, затем удалите промежуточный столбец id

a1.join(b1, Seq("id")).drop("id").show 

+-------+----+------+----+
|   col1|col2|  col3|col4|
+-------+----+------+----+
|  First|   1| india| 980|
|Secound|   2| japan| 990|
|  Third|   3| korea|1000|
| Fourth|   4|chaina| 900|
+-------+----+------+----+
0 голосов
/ 13 февраля 2020

Я пытался сделать это недавно, но безуспешно. Вы можете попробовать преобразовать два объекта в pandas фреймы данных, а затем выполнить слияние.

Шаг # 1:

df1= df1.select("*").toPandas()
df2= df2.select("*").toPandas()

Шаг № 2:

result = pd.concat([df1, df2], axis=1)

Удачи !!

0 голосов
/ 12 февраля 2020

Два набора данных не могут быть объединены без сопоставления данных, кроме использования декартовых. Имена столбцов не обязательно должны быть одинаковыми, но значения в столбце должны быть одинаковыми. При необходимости вы можете объединить 2 кадра данных, используя все их столбцы.

val df1 = //a data frame with columns col1-1, col1-2, col1-3
val df2 = //a data frame with columns col2-1, col2-2, col2-3

val dfJoined = df1.join(df2, df1.col1-1===df2.col2-1 or df1.col1-2===df2.col2-2 or df1.col1-3===df2.col2-3)

//Then drop one set of columns if they have same data.

...