【问题标题】:Spark: equivelant of zipwithindex in dataframeSpark:相当于数据框中的 zipwithindex
【发布时间】:2016-12-27 17:16:54
【问题描述】:

假设我有以下数据框:

dummy_data = [('a',1),('b',25),('c',3),('d',8),('e',1)]
df = sc.parallelize(dummy_data).toDF(['letter','number'])

我想创建以下数据框:

[('a',0),('b',2),('c',1),('d',3),('e',0)]

我所做的是将其转换为rdd 并使用zipWithIndex 函数,然后加入结果:

convertDF = (df.select('number')
              .distinct()
              .rdd
              .zipWithIndex()
              .map(lambda x:(x[0].number,x[1]))
              .toDF(['old','new']))


finalDF = (df
            .join(convertDF,df.number == convertDF.old)
            .select(df.letter,convertDF.new))

数据帧中是否有与zipWIthIndex 类似的功能?还有其他更有效的方法来完成这项任务吗?

【问题讨论】:

标签: python apache-spark pyspark spark-dataframe


【解决方案1】:

请检查 https://issues.apache.org/jira/browse/SPARK-23074 以了解数据帧中的这种直接功能奇偶性。如果您有兴趣在 Spark 中的某个时间点看到这一点,请支持 jira。

以下是 PySpark 中的解决方法:

def dfZipWithIndex (df, offset=1, colName="rowId"):
    '''
        Enumerates dataframe rows is native order, like rdd.ZipWithIndex(), but on a dataframe 
        and preserves a schema

        :param df: source dataframe
        :param offset: adjustment to zipWithIndex()'s index
        :param colName: name of the index column
    '''

    new_schema = StructType(
                    [StructField(colName,LongType(),True)]        # new added field in front
                    + df.schema.fields                            # previous schema
                )

    zipped_rdd = df.rdd.zipWithIndex()

    new_rdd = zipped_rdd.map(lambda args: ([args[1] + offset] + list(args[0])))

    return spark.createDataFrame(new_rdd, new_schema)

abalon 包中也有此功能。

【讨论】:

  • 对于 Python 3+,由于 map 处理元组的方式,需要对此进行微小的更改才能使其工作。以下将作为元组作为单个参数传递,使用 [] 表示法读取元组的元素, new_rdd = zipped_rdd.map(lambda args: ([args[1] + offset] + list(args[0])))
猜你喜欢
  • 1970-01-01
  • 2015-10-11
  • 1970-01-01
  • 2017-11-27
  • 2020-03-07
  • 2014-06-05
  • 2019-06-26
  • 1970-01-01
  • 2019-12-11
相关资源
最近更新 更多