将具有随机生成的假数据的动态数据帧转换为静态数据帧

Posted

技术标签:

【中文标题】将具有随机生成的假数据的动态数据帧转换为静态数据帧【英文标题】:Convert dynamic dataframe with randomly generated fake data to static dataframe 【发布时间】:2022-01-06 08:26:25 【问题描述】:

我正在尝试将一列假数据添加到数据框中。数据框的内容是什么并不重要。我只想添加一列随机生成的假数据,例如,随机生成的名字,每行一个名字。这是一些可以使用的虚拟数据,但我再说一遍,数据框的内容无关紧要:

from faker import Faker

faker = Faker("en_GB")

contact = [faker.profile() for i in range(0, 100)]
contact = spark.createDataFrame(contact)

我正在尝试创建一个具有为不同列执行此操作的函数的类,如下所示:

class anonymise:
        
    @staticmethod
    def FstName():
        def FstName_values():
            faker = Faker("en_GB")
            return faker.first_name()

        FstName_udf = udf(FstName_values, StringType())
        return FstName_udf()

上面的类有一个函数作为例子,但实际的类有多个完全相同模板的函数,只是针对不同的列,例如,LastName。

然后,我在新列中添加如下:

contact = contact \
.withColumn("FstName", anonymise.FstName())

我正在使用这个过程将真实数据替换为逼真的、虚假的、随机生成的数据。

似乎运行良好且运行迅速。但是,我注意到每次显示新数据框时,它都会尝试生成一个全新的列:

第一次尝试:

在第一次之后立即进行第二次尝试:

这意味着数据框不仅仅是一个带有数据的静态数据框,它会尝试为每个后续命令生成一个新列。当我尝试将数据写入外部文件时,这会导致我进一步出现问题。

我希望它使用一些易于调用的静态数据生成一次列。我什至不希望它重新生成相同的数据。生成过程应该发生一次。

我尝试复制到 pandas 数据框,但数据框太大而无法正常工作(1.3+ 百万行),而且我似乎无法将较小的版本写入外部文件。

对此问题的任何帮助表示赞赏!

非常感谢,

卡罗来纳

【问题讨论】:

这是因为您的一列与随机生成的值相关联,因此每次 Spark 运行计算图时,它都会重新计算随机值。设置种子值有帮助吗? 相关:How to fix value produced by Random? @CarolinaKaroullas 我已经尝试使用seed,但它不起作用。 df 每次都会被评估,如果我设置 seed 它将给出相同的名称。这真的很烦人。我会试着考虑一下,但现在我不确定如何解决这个问题。 @VladSiv 感谢您的调查! :) @HussainBohra 我使用的是真实数据,尽管需要用看起来真实的假数据匿名化,使用 Faker 生成的数据用于替换真实数据列。使用 pyspark_anonymizer 不会用真实的假数据替换我的真实数据。 【参考方案1】:

由于您使用的是 spark,它正在跨多个节点进行计算。您可以尝试在匿名化后添加一个contact.persist()。

你可以阅读更多关于坚持HERE。

【讨论】:

您好,感谢您的回复!理论上这会起作用,因为它似乎适用于只有 100 行的测试数据帧。但是,我的实际数据帧中有 240+ 千和 1.3+ 百万行,并且 .cache() 和 .persist() 似乎不适用于这些(就像我尝试在缓存/持久后显示数据帧和该命令在半小时后仍然运行)。您对大型数据框有什么建议吗?谢谢:) 我对此进行了一些阅读,根据此处提到的文档docs.microsoft.com/en-us/azure/databricks/kb/jobs/…,它说如果数据帧非常大,您应该先将其写入镶木地板文件。然后,您可以再次阅读它以获得持久的 DF。另一种选择是将原始 spark df 转换为 pandas df,添加假列并将其转换回 sparkdf。这两个选项都很老套,可能需要一些时间,但会奏效。【参考方案2】:

所以最后这是一个非常简单的修复......

通过将faker = Faker("en_GB") 放在它所在的函数中,我为每一行生成了一个faker 的实例。我只需要从函数中删除它并在类之外生成实例。所以现在,虽然每次调用命令时它都会生成数据,但即使对于大型数据帧,它也会非常快,而且我没有遇到任何后续命令的任何问题。

【讨论】:

以上是关于将具有随机生成的假数据的动态数据帧转换为静态数据帧的主要内容,如果未能解决你的问题,请参考以下文章

使用R将列表中具有不同日期的数据帧转换为单个数据帧

将火花数据帧动态转换为元组数据集(字符串,_<:产品)

将 dict 转换为具有更高级别的数据帧

Pyspark 将 rdd 转换为具有空值的数据帧

spark scala比较具有时间戳列的数据帧

将具有嵌套结构的 MATLAB 文件转换为数据帧字典