Spark — сохранение широкого/разреженного фрейма данных

Я хочу сохранить очень широкий кадр данных Spark (> 100 000 столбцов), который редко заполняется (> 99% значений являются нулевыми), сохраняя при этом только ненулевые значения (чтобы избежать затрат на хранение):

  • Каков наилучший формат для такого варианта использования (HBase, Avro, Parquet, ...)?
  • Что нужно указать на стороне Spark, чтобы игнорировать нули при записи?

Обратите внимание, что я уже пробовал Parquet и Avro с простым df.write statement - для df размером ок. 100x130k Parquet работает хуже всего (около 55 МБ) по сравнению с Avro (около 15 МБ). Для меня это говорит о том, что ВСЕ нулевые значения сохраняются.

Спасибо !


person py-r    schedule 09.01.2021    source источник
comment
как насчет разреженных векторов?   -  person thebluephantom    schedule 09.01.2021
comment
@thebluephantom: Спасибо за ваше предложение. Любая идея, как сохранять разреженные векторы?   -  person py-r    schedule 09.01.2021


Ответы (1)


Spark to JSON/SparseVector (из thebluephantom)

В пыспарке и с помощью мл. В противном случае конвертируйте в Scala.

%python
from pyspark.sql.types import StructType, StructField, DoubleType
from pyspark.ml.linalg import SparseVector, VectorUDT

temp_rdd = sc.parallelize([
    (0.0, SparseVector(4, {1: 1.0, 3: 5.5})),
    (1.0, SparseVector(4, {0: -1.0, 2: 0.5}))])

schema = StructType([
    StructField("label", DoubleType(), False),
    StructField("features", VectorUDT(), False)
])

df = temp_rdd.toDF(schema)
df.printSchema()
df.write.json("/FileStore/V.json")


df2 = spark.read.schema(schema).json("/FileStore/V.json")
df2.show()

возвращается после чтения:

+-----+--------------------+
|label|            features|
+-----+--------------------+
|  1.0|(4,[0,2],[-1.0,0.5])|
|  0.0| (4,[1,3],[1.0,5.5])|
+-----+--------------------+

Spark to Avro/Avro2TF (из py-r)

Библиотека Avro2TF, представленная в этом руководстве, кажется интересной альтернативой, напрямую использует Avro. В результате разреженный вектор будет закодирован следующим образом:

+---------------------+--------------------+
|genreFeatures_indices|genreFeatures_values|
+---------------------+--------------------+
|     [2, 4, 1, 8, 11]|[1.0, 1.0, 1.0, 1...|
|          [11, 10, 3]|     [1.0, 1.0, 1.0]|
|            [2, 4, 8]|     [1.0, 1.0, 1.0]|
|             [11, 10]|          [1.0, 1.0]|
|               [4, 8]|          [1.0, 1.0]|
|         [2, 4, 7, 3]|[1.0, 1.0, 1.0, 1.0]|
person thebluephantom    schedule 09.01.2021
comment
Спасибо - это настоящий разреженный формат! Не знаете, можно ли получить аналогичную структуру в Avro/Parquet, в т.ч. метаданные? А как насчет HBase? Действительно, я хотел бы быть эффективным и во время запроса;) Спасибо! - person py-r; 09.01.2021
comment
авро и паркет диаметрально противоположны. один ряд, один столбец. вся идея запасного формата заключается в экономии места. - person thebluephantom; 09.01.2021
comment
Спасибо, но вы говорите, что be определение Avro или Parquet не поддерживают разреженную структуру, т.е. должны хранить все нули? А как насчет HBase? - person py-r; 09.01.2021
comment
не вижу проблем с JSON, если у вас есть ключ, если вы не хотите прямого доступа. плотный вектор в массив для avro, хотя и не разреженный. - person thebluephantom; 09.01.2021
comment
ты прав, поэтому я предлагаю json. - person thebluephantom; 09.01.2021
comment
sparse больше подходит для машинного обучения памяти. - person thebluephantom; 09.01.2021
comment
Как насчет формата AvroTF github.com/linkedin/Avro2TF? - person py-r; 09.01.2021
comment
А как насчет HBase? - person py-r; 09.01.2021
comment
жесткий трепать братан - person thebluephantom; 09.01.2021
comment
Ага ! Даю вам точку для json, спасибо. Я задал еще один вопрос для HBase, так как хотел бы уточнить это: stackoverflow.com/questions/65647574/ - person py-r; 10.01.2021