如何从“参考文件”中推断出架构并将其用作要读取的文件的参考?

Posted

技术标签:

【中文标题】如何从“参考文件”中推断出架构并将其用作要读取的文件的参考?【英文标题】:How to infer a schema from a "reference file" and apply it as a reference to files to be read in? 【发布时间】:2020-09-30 08:46:39 【问题描述】:

我有大量的 csv 文件可以读入包含 100 多列的 Spark (Databricks)。我不想手动指定架构并考虑使用以下方式。读入“参考”csv 文件,从此文件中获取架构并将其作为“reference_schema”应用于我需要读入的所有其他文件。代码如下所示(但我无法让它工作)。

# File location and type
file_location = "/FileStore/tables/reference_file_with_ok_schema.csv"
file_type = "csv"

# CSV options
infer_schema = "True"
first_row_is_header = "True"
delimiter = ";"

df = spark.read.format(file_type) \
  .option("inferSchema", infer_schema) \
  .option("header", first_row_is_header) \
  .option("sep", delimiter) \
  .load(file_location)

mySchema = df.schema ###this is probably where I go wrong

display(df)

接下来我将应用 mySchema 作为新 csv 的参考 Schema,如下例所示:

# File location and type
file_location = "/FileStore/tables/all_other_files.csv"
file_type = "csv"

# CSV options
first_row_is_header = "True"
delimiter = ";"

# The applied options are for CSV files. For other file types, these will be ignored.
df = spark.read.format(file_type) \
  .schema(mySchema) \
  .option("header", first_row_is_header) \
  .option("sep", delimiter) \
  .load(file_location)

display(df)

这只会产生空值

提前感谢您的帮助和 最好的祝福 亚历克斯

【问题讨论】:

【参考方案1】:

你有正确的方法。

您可以检查这两个选项modecolumnNameOfCorruptRecord。默认情况下,mode=PERMISSIVE 在行与架构不匹配时创建 NULL 记录。 这可能就是为什么您的数据框中有 NULL 记录的原因,这意味着架构 mySchema 和文件 all_other_files 的架构不同。

首先要检查的是推断all_other_files 的架构并将其与mySchema 进行比较。为了轻松做到这一点,schema 对象有一个 json 方法将它们输出为 JSON 字符串。人类比较两个 json 比比较 2 个模式对象更容易。

mySchema.json()

如果只有一处不同,不幸的是整行都会被设置为 NULL。

【讨论】:

嗨史蒂文,你似乎是对的。在一列中,所有值都属于不同类型。奇怪的是,columnNameOfCorruptRecord 没有出现在数据框中。原始列都带有 NULL,但缺少附加的“损坏”列。有什么想法吗? @DocAl 如果您不设置任何内容,它将使用spark.sql.columnNameOfCorruptRecord 中指定的值。也许,这个值也是空的,因此,输出中没有损坏的列。但是您可以在选项中手动设置它。检查csv 方法中可用的参数。 我确实使用 .option("columnNameOfCorruptRecord", "row_corrupt") 明确设置了它。可能因为我使用的是架构而无法显示?最佳亚历克斯 @DocAl 显然,您需要将该列添加到原始模式中。 mySchema.add(field, data_type=None, nullable=True, metadata=None)。 ***.com/questions/58631365/… 添加了该字段,它现在似乎可以工作了。仍然需要测试,但非常感谢史蒂文。最佳亚历克斯

以上是关于如何从“参考文件”中推断出架构并将其用作要读取的文件的参考?的主要内容,如果未能解决你的问题,请参考以下文章

如何将文本文件中的值分配给python函数中的数组并将其用作全局?

如何从以下架构中选择列“?

如何告诉gdb'优化输出值'的值或使其推断出值?

如何从可用的BasicAWSCredentials中推断出AWS账户ID?

在python中,窃取一个B类方法并将其用作A类方法中的A类实例

计算器 - 尝试从“for”中获取第一个数字并将其用作 INIT_VALUE