如何在PySpark数据框中添加具有备用值的列?

时间:2019-08-27 20:32:19

标签: apache-spark pyspark pyspark-sql

我有以下示例数据框

df = spark.createDataFrame([('start','end'), ('start1','end1')] ,["start", "end"])

,我想爆炸每行中的值,并在生成的行中关联交替的1-0值。这样,我可以识别每行中的开始/结束条目。

我能够通过这种方式达到预期的结果

from pyspark.sql.window import Window
w = Window().orderBy(lit('A'))
df = (df.withColumn('start_end', fn.array('start', 'end'))
        .withColumn('date', fn.explode('start_end'))
        .withColumn('row_num', fn.row_number().over(w)))
df = (df.withColumn('is_start', fn.when(fn.col('row_num')%2 == 0, 0).otherwise(1))
        .select('date', 'is_start'))

给出

| date   | is_start |
|--------|----------|
| start  | 1        |
| end    | 0        |
| start1 | 1        |
| end1   | 0        |

但是对于这样一个简单的任务来说似乎太复杂了。

有没有不使用UDF的更好/更清洁的方法?

3 个答案:

答案 0 :(得分:1)

您可以尝试data.groupby(['Month/Year'])[['col1','col2','col3','col4']].sum()

union
df = spark.createDataFrame([('start','end'), ('start1','end1')] ,["start", "end"])
df = df.withColumn('startv', F.lit(1))
df = df.withColumn('endv', F.lit(0))
df = df.select(['start', 'startv']).union(df.select(['end', 'endv']))
df.show()

您可以重命名列并从此处开始重新排列行。

答案 1 :(得分:1)

我的用例中也有类似情况。在我的情况下,我有巨大的数据集(〜50GB),并且进行任何自连接/重转换都会导致更多的内存和不稳定的执行。

我又进一步降低了数据集的层次,并使用了 rdd 的平面图。这将使用地图端转换,并且在改组,cpu和内存方面将具有成本效益。

df = spark.createDataFrame([('start','end'), ('start1','end1')] ,["start", "end"])
df.show()
+------+----+
| start| end|
+------+----+
| start| end|
|start1|end1|
+------+----+

final_df = df.rdd.flatMap(lambda row: [(row.start, 1), (row.end, 0)]).toDF(['date', 'is_start'])
final_df.show()
+------+--------+
|  date|is_start|
+------+--------+
| start|       1|
|   end|       0|
|start1|       1|
|  end1|       0|
+------+--------+

答案 2 :(得分:1)

您可以将pyspark.sql.functions.posexplodepyspark.sql.functions.array一起使用。

首先在startend列中创建一个数组,然后使用以下位置将其爆炸:

from pyspark.sql.functions import array, posexplode

df.select(posexplode(array("end", "start")).alias("is_start", "date")).show()
#+--------+------+
#|is_start|  date|
#+--------+------+
#|       0|   end|
#|       1| start|
#|       0|  end1|
#|       1|start1|
#+--------+------+