使用 pyspark 从平面记录创建段数组

Using pyspark to create a segment array from a flat record

我有一个人口稀少的 table,其中包含针对唯一用户 ID 的各个细分市场的值。我需要创建一个包含 unique_id 和相关段 headers 的数组

请注意,这只是一个指示性数据集。我有几百个这样的片段。

------------------------------------------------
| user_id   | seg1 | seg2 | seg3 | seg4 | seg5 |
------------------------------------------------
| 100       |   M  |  null|   25 |  null|  30  |
| 200       |  null|  null|   43 |  null|  250 |
| 300       |   F  |  3000|  null|  74  |  null|
------------------------------------------------

我希望输出是

-------------------------------
| user_id| segment_array      |
-------------------------------
| 100    | [seg1, seg3, seg5] |
| 200    | [seg3, seg5]       |
| 300    | [seg1, seg2, seg4] |
-------------------------------

pyspark-sql 的 pyspark 中是否有可用的函数来完成此操作?

感谢您的帮助!

不确定这是最好的方法,但我会这样攻击它:

有一个 collect_set 函数,它始终会在您聚合的值列表中为您提供唯一值。

为每个段做联合:

df_seg_1 = df.select(
  'user_id', 
  fn.when(
    col('seg1').isNotNull(), 
    lit('seg1)
  ).alias('segment')
)
# repeat for all segments

df = df_seg_1.union(df_seg_2).union(...)

df.groupBy('user_id').agg(collect_list('segment'))

我找不到直接的方法,但你可以这样做。

cols= df.columns[1:]

r = df.withColumn('array', array(*[when(col(c).isNotNull(), lit(c)).otherwise('notmatch') for c in cols])) \
  .withColumn('array', array_remove('array', 'notmatch'))
r.show()
+-------+----+----+----+----+----+------------------+
|user_id|seg1|seg2|seg3|seg4|seg5|             array|
+-------+----+----+----+----+----+------------------+
|    100|   M|null|  25|null|  30|[seg1, seg3, seg5]|
|    200|null|null|  43|null| 250|      [seg3, seg5]|
|    300|   F|3000|null|  74|null|[seg1, seg2, seg4]|
+-------+----+----+----+----+----+------------------+