簡體   English   中英

如何在 AWS Glue 中正確重命名動態數據幀的列?

[英]How to properly rename columns of dynamic dataframe in AWS Glue?

我加載 JSON 數據並在動態數據幀上使用關系化方法來展平原本嵌套的 JSON 對象並將其保存為鑲木地板格式。 問題是,一旦為更快的 Athena 查詢保存為 parquet 格式,列名包含點,這違反了 Athena SQL 查詢語法,因此我無法進行特定於列的查詢。

為了解決這個問題,我還重命名了 Glue 作業中的列名以排除點並使用下划線代替。 我的問題是兩者中的哪種方法會更好,為什么? (效率-內存?節點上的執行速度?等)。

還考慮到可怕的 aws 膠水文檔,我無法提出僅動態框架的解決方案。 我在以動態方式獲取列名時遇到問題,因此我正在使用 toDF()。

1) 第一種方法是從動態 df 中提取的 df 中獲取列名

relationalize1 = Relationalize.apply(frame=datasource0, transformation_ctx="relationalize1").select("roottable")
    df_relationalize1 = relationalize1.toDF()
    for field in df_relationalize1.schema.fields:
        relationalize1 = RenameField.apply(frame = relationalize1, old_name = "`"+field.name+"`", new_name = field.name.replace(".","_"), transformation_ctx = "renamefield_" + field.name)

2)第二種方法是從動態df中提取df並在pyspark df(而不是動態df)上執行重命名字段,然后轉換回動態df並將其保存為鑲木地板格式。

有沒有更好的方法? 爬蟲可以重命名列嗎? .fromDF() 方法有多快? 是否有比 pdf 開發人員指南更好的函數和方法文檔?

該問題專門詢問重命名:

(a) 轉換為DataFrame
(b) 以與old_columns相同的順序創建具有所需列名的new_columns數組。
(c) 使用functools.reduce()pyspark.withColumnRenamed()覆蓋和持久化new_columns
(d) 轉換回DynamicFrame

 from awsglue.job import Job from awsglue.context import GlueContext from pyspark.context import SparkContext from functools import reduce JOB_NAME = "csv_to_parquet" sc = SparkContext() glue_context = GlueContext(sc) job = Job(glue_context) job.init(JOB_NAME) # Create DynamicFrame datasource = glue_context.create_dynamic_frame_from_options( connection_type="s3", format="csv", connection_options={"paths": ["s3://path/to/source/file.csv"]}, format_options={"withHeader": True, "separator": chr(44)}, # comma delimited ) # (a) Convert to DataFrame df = datasource.toDF() # (b) Create array with desired columns old_columns = df.schema.names new_columns = [ field.lower().replace(" ", "_").replace(".", "_") for field in old_columns ] # (c) Overwrite and persist `new_columns` df = reduce( lambda df, idx: df.withColumnRenamed(old_columns[idx], new_columns[idx]), range(len(old_columns)), df, ) # (d) Convert back to DynamicFrame datasource = datasource.fromDF(df, glue_context, "datasource") # Write DynamicFrame as Parquet datasink = glue_context.write_dynamic_frame_from_options( frame=datasource, connection_type="s3", connection_options={"path": "s3://path/to/target/prefix/"}, format="parquet", )

塊引用

您可以使用schema屬性訪問 DynamicFrame 的schema 從中您可以定義任何包含. 到使用_新列。 您只需要知道列的類型和名稱即可使用ApplyMapping轉換執行此操作

也許:

from awsglue.transforms import ApplyMapping    

# construct renaming mapping for ApplyMapping
mappings = list()
for field in df.schema.fields:
    if '.' in field.name:
        dtype = field.dataType.typeName()
        mappings.append((field.name, dtype, field.name.replace('.', '_'), dtype))

# apply mapping
renamed = ApplyMapping(frame=df, mappings=mappings)    

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM