Pyspark 如何在Palantir Foundry中合并多个动态输入?

Pyspark 如何在Palantir Foundry中合并多个动态输入?,pyspark,dynamic,union,palantir-foundry,Pyspark,Dynamic,Union,Palantir Foundry,我想在Palantir Foundry中合并多个数据集,数据集的名称是动态的,因此我无法在transforms_df(..)中静态地给出数据集名称。有没有一种方法可以在转换中动态地接受多个输入并合并所有这些数据帧 我尝试在数据集上循环,如: li=['dataset1\u路径','dataset2\u路径'] union_df = None for p in li: @transforms_df( my_input = Input(p), Output(p+"_o

我想在Palantir Foundry中合并多个数据集,数据集的名称是动态的,因此我无法在transforms_df(..)中静态地给出数据集名称。有没有一种方法可以在转换中动态地接受多个输入并合并所有这些数据帧

我尝试在数据集上循环,如:

li=['dataset1\u路径','dataset2\u路径']

union_df = None
for p in li:
  @transforms_df(
    my_input = Input(p), 
    Output(p+"_output")
  )

  def my_compute_function(my_input):
    return my_input

  if union_df is None:
    union_df = my_compute_function
  else:
    union_df = union_df.union(my_compute_function)

但是,这不会生成联合输出


任何帮助都将不胜感激,谢谢。

这应该可以对您进行一些更改,这是一个带有json文件的动态数据集示例,您的情况可能会略有不同。这里是一种通用的方法,您可以使用动态json输入数据集,该数据集应适用于任何类型的动态输入文件类型或您可以指定的foundry数据集的内部。这个通用示例处理一组上传到平台中dataset节点的json文件。这应该是完全动态的。在这之后建立工会应该是一件简单的事情

这里也有一些额外的日志记录

希望这有帮助

from transforms.api import Input, Output, transform
from pyspark.sql import functions as F
import json
import logging


def transform_generator():
    transforms = []
    transf_dict = {## enter your dynamic mappings here ##}

    for value in transf_dict:
        @transform(
            out=Output(' path to your output here '.format(val=value)),
            inpt=Input(" path to input here ".format(val=value)),
        )
        def update_set(ctx, inpt, out):
            spark = ctx.spark_session
            sc = spark.sparkContext

            filesystem = list(inpt.filesystem().ls())
            file_dates = []
            for files in filesystem:
                with inpt.filesystem().open(files.path) as fi:
                    data = json.load(fi)
                file_dates.append(data)

            logging.info('info logs:')
            logging.info(file_dates)
            json_object = json.dumps(file_dates)
            df_2 = spark.read.option("multiline", "true").json(sc.parallelize([json_object]))
            df_2 = df_2.withColumn('upload_date', F.current_date())

            df_2.drop_duplicates()
            out.write_dataframe(df_2)
        transforms.append(update_logs)
    return transforms


TRANSFORMS = transform_generator()

这应该可以对您进行一些更改,这是一个带有json文件的动态数据集示例,您的情况可能会略有不同。这里是一种通用的方法,您可以使用动态json输入数据集,该数据集应适用于任何类型的动态输入文件类型或您可以指定的foundry数据集的内部。这个通用示例处理一组上传到平台中dataset节点的json文件。这应该是完全动态的。在这之后建立工会应该是一件简单的事情

这里也有一些额外的日志记录

希望这有帮助

from transforms.api import Input, Output, transform
from pyspark.sql import functions as F
import json
import logging


def transform_generator():
    transforms = []
    transf_dict = {## enter your dynamic mappings here ##}

    for value in transf_dict:
        @transform(
            out=Output(' path to your output here '.format(val=value)),
            inpt=Input(" path to input here ".format(val=value)),
        )
        def update_set(ctx, inpt, out):
            spark = ctx.spark_session
            sc = spark.sparkContext

            filesystem = list(inpt.filesystem().ls())
            file_dates = []
            for files in filesystem:
                with inpt.filesystem().open(files.path) as fi:
                    data = json.load(fi)
                file_dates.append(data)

            logging.info('info logs:')
            logging.info(file_dates)
            json_object = json.dumps(file_dates)
            df_2 = spark.read.option("multiline", "true").json(sc.parallelize([json_object]))
            df_2 = df_2.withColumn('upload_date', F.current_date())

            df_2.drop_duplicates()
            out.write_dataframe(df_2)
        transforms.append(update_logs)
    return transforms


TRANSFORMS = transform_generator()

所以这个问题分为两个问题

如何使用编程输入路径处理转换 要使用编程输入处理转换,重要的是要记住两件事:

第一-转换将在CI时间确定您的输入和输出。这意味着您可以使用生成转换的python代码,但不能从数据集中读取路径,它们需要硬编码到生成转换的python代码中

第二个-在CI执行期间,将创建一次转换。这意味着无论何时构建数据集,都不能使用增量或特殊逻辑来生成不同的路径

有了这两个前提,比如在您的示例中或@jeremy david gamet的(ty的回答是,给了您一个+1)中,您可以使用python代码在CI时间生成路径

dataset\u path=['dataset1\u path','dataset2\u path']
对于数据集_路径中的路径:
@变换(
我的输入=输入(路径),
输出(f“{path}\u输出”)
)
定义my_compute_函数(my_输入):
返回我的输入
但是,要合并它们,您需要第二次转换来执行合并,您需要传递多个输入,因此您可以使用
*args
**kwargs
来执行以下操作:

dataset\u path=['dataset1\u path','dataset2\u path']
所有参数=[数据集中路径的输入(路径)]
所有参数追加(输出(“路径/到/联合的数据集”))
@变换_df(*所有参数)
def my_compute_函数(*args):
输入_dfs=[]
对于args中的arg:
#args列表中还有其他参数,如ctx,因此我们需要检查类型。你也可以用kwargs来表达更多的决定论。
如果isinstance(arg,pyspark.sql.DataFrame):
输入\u dfs.append(arg)
#现在,您的dfs已包含在列表中,您可以合并它们
#注意我没有测试这段代码,但应该是这样的
...
如何使用不同的模式合并数据集。 对于这一部分,有很多关于如何在spark中合并不同数据帧的问答。下面是从中复制的一个简短代码示例

从pyspark.sql导入SparkSession,HiveContext
从pyspark.sql.functions导入
从pyspark.sql导入行
def客户联盟(df1、df2):
cols1=df1.0列
cols2=df2.0列
总计=已排序(cols1+列表(集合(cols2)-集合(cols1)))
def expr(mycols、allcols):
def processCols(colname):
如果在mycols中使用colname:
返回colname
其他:
返回灯(无)。别名(colname)
cols=map(processCols,allcols)
退货清单(cols)
追加=df1.select(expr(cols1,total_cols)).union(df2.select(expr(cols2,total_cols)))
附加的返回

所以这个问题分为两个问题

如何使用编程输入路径处理转换 要使用编程输入处理转换,重要的是要记住两件事:

第一-转换将在CI时间确定您的输入和输出。这意味着您可以使用生成转换的python代码,但不能从数据集中读取路径,它们需要硬编码到生成转换的python代码中

第二个-在CI执行期间,将创建一次转换。这意味着无论何时构建数据集,都不能使用增量或特殊逻辑来生成不同的路径

有了这两个前提,比如在您的示例中或@jeremy david gamet的(ty的回答是,给了您一个+1)中,您可以使用python代码在CI时间生成路径

dataset\u path=['dataset1\u path','dataset2\u path']
对于数据集_路径中的路径:
@变换(
我的输入=输入(路径),
输出(f“{path}\u输出”)
)
定义my_compute_函数(my_输入):
返回我的输入
但是,要合并它们,您需要第二次转换来执行合并,您需要传递多个输入,因此您可以使用
*args
**kwargs
来执行以下操作:

dataset\u path=['dataset1\u path','dataset2\u path']
所有参数=[数据集中路径的输入(路径)]
所有参数追加(输出(“路径/到/联合的数据集”))
@变换_df(*所有参数)
def my_compute_函数(*args):
输入_dfs=[]
对于arg in