从PySpark DataFrame中删除所有StructType列

4

我有一个数据框df,读取的JSON文件如下:

df = spark.read.json("/myfiles/file1.json")

df.dtypes 显示以下列和数据类型:

id  string
Name - struct
address - struct
Phone - struct
start_date - string
years_with_company - int
highest_education - string
department - string
reporting_hierarchy - struct

我想提取非struct类型的列并创建一个数据框。例如,我的结果数据框应该只有idstart_datehighest_educationdepartment这些列。

以下是我部分可用的代码,因为我只得到了最后一个非struct类型的列department的值。我想收集所有的非struct类型列并将其转换为数据框:

names = df.schema.names

for col_name in names:
   if isinstance(df.schema[col_name].dataType, StructType):
      print("Skipping struct column %s "%(col_name))
   else:
      df1 = df.select(col_name).collect() 

我相信这可能不是最好的方法,而且我有一些想不出来的问题,所以我希望得到你的帮助。谢谢。


1个回答

5

使用列表推导式:

cols_filtered = [
    c for c in df.schema.names 
    if not isinstance(df.schema[c].dataType, StructType) 
]    

或者,

# Thank you @pault for the suggestion!
cols_filtered = [c for c, t in df.dtypes if t != 'struct']

现在,您可以将结果传递给df.select
df2 = df.select(*cols_filtered)

1
非常感谢,我使用了NOT表达式,因为isinstance只给了我结构类型 :) 以下对我有用。非常感谢您的帮助。cols_filtered = [c for c in df.schema.names if not isinstance(df.schema[c].dataType, StructType)]df1 = df.select(*cols_filtered) - Sameer
@Sameer 我为粗糙的回答道歉。感谢您的修正! - cs95
1
你可以使用以下代码 cols_filtered = [c for c, t in df.dtypes if t != 'struct'] 来避免调用 isinstance - pault
@pault - 有趣的是,原始解决方案对我有效,而新的解决方案则无效。也许'struct'不是一个有效的数据类型(dtypes),但这就是内部spark在模式中表示structtype的方式。将数据类型与struct进行比较并没有给我想要的结果,但检查是否为StructType的isinstance却有效。'https://spark.apache.org/docs/1.5.2/api/java/org/apache/spark/sql/types/package-frame.html。感谢您的帮助。 - Sameer
@pault 抱歉耽搁了,df.dtypes 会在打印模式时显示结构和数据类型。 - Sameer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接