如何从 pyspark 数据框的模式属性(来自镶木地板文件)中获取特定字段名称的数据类型?

Posted

技术标签:

【中文标题】如何从 pyspark 数据框的模式属性(来自镶木地板文件)中获取特定字段名称的数据类型?【英文标题】:How to get datatype for specific field name from schema attribute of pyspark dataframe (from parquet files)? 【发布时间】:2020-02-04 00:06:48 【问题描述】:

有一个我正在读入 pyspark 会话的镶木地板文件文件夹。如何检查/解析单个架构字段类型和其他信息(例如,为了比较数据帧之间的架构以查看确切的类型差异)?

我可以看到 parquet 架构和特定字段名称,例如...

from pyspark.sql import SparkSession
from pyspark.sql.functions import *
sparkSession = SparkSession.builder.appName("data_debugging").getOrCreate()

df = sparkSession.read.option("header", "true").parquet("hdfs://hw.co.local:8020/path/to/parquets")
df.schema # or df.printSchema()
df.fieldNames()

所以我可以看到架构

StructType(List(StructField(SOME_FIELD_001,StringType,true),StructField(SOME_FIELD_002,StringType,true),StructField(SOME_FIELD_003,StringType,true)))

但不确定如何获取特定字段的值,例如。类似...

df.schema.getType("SOME_FIELD_001")
or
df.schema.getData("SOME_FIELD_001")  #type: dict

有谁知道如何做这样的事情?

【问题讨论】:

【参考方案1】:

此函数将(名称、类型、可空性)收集在一个字典中,并且可以根据数据框的列名轻松查找信息。

如果 name 指定为 df,则元数据字典将被称为 df.meta

name=df #enter name of dataframe here
def metadata(name): #function for getting metadata in a dict
  null=[str(n.nullable) for n in name.schema.fields] #nullability
  types=[str(i.dataType) for i in name.schema.fields] #type 
  both = [list(a) for a in zip(types, null)]#combine type+nullability
  names= name.columns #names of columns
  final =  #create dict
  for key in names: 
     for value in both: 
          final[key] = value
          both.remove(value)
          break
  return final
name.meta= metadata(name) #  final dict is called df.meta
                          # if name=df2, final dict will be df2.meta

现在您可以比较不同数据框的列信息了。

示例:

Input: df.meta
Output: 'col1': ['StringType', 'True'],
         'col2': ['StringType', 'True'],
         'col3': ['LongType', 'True'],
         'col4': ['StringType', 'True']

#get column info
Input: df.meta['col1']
Output: ['StringType', 'True']

#compare column type + nullability
Input: df.meta['col1'] == df2.meta['col1']
Ouput: True/False


#compare only column type
Input: df.meta['col1'][0] == df2.meta['col1'][0]
Output: True/False

#compare only nullability
Input: df.meta['col1'][1] == df2.meta['col1'][1]
Output: True/False

【讨论】:

【参考方案2】:

方法一:

您可以使用df.dtypes 方法获取字段名称及其数据类型,并将其转换为dict 对象,如下所示,

myschema = dict(df.dtypes)

现在,您可以获得如下所示的数据类型,

myschema.get('some_field_002')

输出:

'string'

方法二:

或者,如果您希望数据类型为pyspark.sql.types 对象,您可以使用df.schema 方法并创建一个自定义模式字典,如下所示,

myschema = dict(map(lambda x: (x.name, x.dataType), df.schema.fields))

print(myschema.get('some_field_002'))

输出:

StringType

【讨论】:

以上是关于如何从 pyspark 数据框的模式属性(来自镶木地板文件)中获取特定字段名称的数据类型?的主要内容,如果未能解决你的问题,请参考以下文章

将pyspark数据框的列转换为小写

如何在数据框的开头移动 pyspark 数据框的特定列

将列字典从不同的数据帧转换为数据帧:pyspark

从列表中创建一个 pyspark 数据框列,其中列表的长度与数据框的行数相同

如何在 pyspark 中创建数据框的副本?

如何在 pyspark 中加入带有熊猫数据框的配置单元表?