foreachPartition()自定义函数中的PySpark Access DataFrame列

时间:2018-05-22 00:11:11

标签: python apache-spark dataframe iterator pyspark

我有一个名为"内部"的函数。我想将此函数应用于pyspark数据帧。为此,我打电话给" foreachPartition(内部)"我创建的数据帧上的方法。 "内部" function需要dataframe的值。

数据框如下所示:

>>> small_df
DataFrame[lon: double, lat: double, t: bigint]

代码如下所示:

def inside(iterator):
    row=iterator
    x=row.lon
    y=row.lat
    i=row.t 
    #do more stuff

small=pliades.iloc[0:20000,:] #take sample of rows from big dataset
small_df=sqlContext.createDataFrame(small) #create dataframe
test=small_df.foreachPartition(inside)

我的问题是:x,y,我如何分别获得数据帧的第一(lon),第二(lat)和第三(t)列的值?

我还尝试使用row.lon,row.select,将其视为列表,但无法获得所需的结果。

1 个答案:

答案 0 :(得分:1)

foreachRDD[Row]上运行,每个分区都为Iterator[Row]。如果您想要列出所有值(由于可能的内存问题,不建议使用

def inside(iterator):
    x, y, i = zip(*iterator)
    ...
    yield ...

一般来说,最好只是逐行迭代行,而不是全部保留在内存中:

def inside(iterator):
    for x, y, i in iterator:
        yield ...

您还可以考虑使用pandas_udf

  • 如果函数返回相同数量的值且只有一列,则可以使用标量类型,该类型需要pandas.Series并返回pandas.Series

    from pyspark.sql.functions import pandas_udf, PandasUDFType
    
    @pandas_udf(schema, PandasUDFType.SCALAR)
    def f(*cols: pandas.Series) -> pandas.Series:
        ...
    
    df.select(f("col1", "col2", ...))
    
  • 分组变体,它带有pandas.DataFrame并返回pandas.DataFrame,行数相同或不同:

    from pyspark.sql.functions import spark_partition_id
    
    
    
    @pandas_udf(schema, PandasUDFType.GROUPED_MAP)
    def g(df: pandas.DataFrame) -> pandas.DataFrame:
        ...
    
    df.groupby(spark_partition_id()).apply(g)