У меня есть таблица с (миллионами) записей в соответствии со строками следующего примера, прочитанными в фрейме данных Spark (sdf
):
Идентификатор | С1 | С2 |
---|---|---|
хх1 | с118 | c219 |
хх1 | с113 | c218 |
хх1 | с118 | c214 |
акб | с121 | с201 |
e3d | c181 | c221 |
e3d | с132 | c252 |
abq | с141 | c290 |
... | ... | ... |
вы1 | c13023 | C23021 |
Я хотел бы получить меньшее подмножество этих идентификатор для дальнейшей обработки. Я идентифицирую уникальный набор идентификатор в таблице с помощью sdf_id = sdf.select("Id").dropDuplicates()
.
Каков эффективный способ фильтрации данных (С1, С2), относящихся, скажем, к 100 случайно выбранным идентификатор?
Привет @pltc, мне нужны полные данные для каждого идентификатора для подмножества идентификаторов.
Поскольку у вас уже есть список уникальных ids
, вы можете дополнительно отобрать его до нужной фракции и отфильтровать на основе этого.
Есть и другие способы выборки случайных идентификаторов, которые можно найти здесь.
### Assuming the DF is 1 mil records , 100 records would be 0.01%
sdf_id = sdf.select("Id").dropDuplicates().sample(0.01).collect()
sdf_filtered = sdf.filter(F.col('Id').isin(sdf_id))
Спасибо, Вабхав. Я могу успешно выполнить выборку, но получаю следующую ошибку на этапе фильтрации. ``` Произошла ошибка при вызове z:org.apache.spark.sql.functions.lit. : java.lang.RuntimeException: неподдерживаемый литеральный тип класса java.util.ArrayList``` Есть ли у вас какие-либо предложения по исправлению?
Есть несколько способов добиться желаемого.
df = spark.createDataFrame([
(1, 'a'),
(1, 'b'),
(1, 'c'),
(2, 'd'),
(2, 'e'),
(3, 'f'),
], ['id', 'col'])
ids = df.select('id').distinct().sample(0.2) # 2 is 20%, you can adjust this
+---+
| id|
+---+
| 1|
+---+
Поскольку у вас есть два фрейма данных, вы можете просто выполнить одно внутреннее соединение, чтобы получить все записи из df
для каждого идентификатора в ids
. Обратите внимание, что F.broadcast
предназначен для повышения производительности, потому что ids
должен быть достаточно маленьким. Не стесняйтесь забрать его, если хотите. С точки зрения производительности этот подход предпочтительнее.
df.join(F.broadcast(ids), on=['id'], how='inner').show()
+---+---+
| id|col|
+---+---+
| 1| a|
| 1| b|
| 1| c|
+---+---+
isin
Вы не можете просто получить список идентификаторов через ids.collect()
, потому что это вернет список Row
, вам нужно перебрать его, чтобы получить именно тот столбец, который вы хотите (в данном случае id
).
df.where(F.col('id').isin([r['id'] for r in ids.collect()])).show()
+---+---+
| id|col|
+---+---+
| 1| a|
| 1| b|
| 1| c|
+---+---+
Вам нужен полные данные по идентификатору для подмножества идентификаторов? или любое подмножество записей в порядке?