【Pyspark】 一列变多列 、分割 一行中的list分割转为多列 explode,多列变一列(可保持原顺序), 多行变一行

目录

 

一、一列变多列  、分割 一行中的list分割转为多列 explode

二、多列变一列

多列变一列并保持原顺序

三、多行变一行

附录:DataFrame添加新的一列


一、一列变多列  、分割 一行中的list分割转为多列 explode

官方例子:Python pyspark.sql.functions.explode() Examples

https://www.programcreek.com/python/example/98237/pyspark.sql.functions.explode

 

根据某个字段内容进行分割,然后生成多行,这时可以使用explode方法

Eg:

df.explode("c3","c3_"){time: String => time.split(" ")}.show(False)

https://blog.csdn.net/anshuai_aw1/article/details/87881079#4.4%C2%A0%E5%88%86%E5%89%B2%EF%BC%9A%E8%A1%8C%E8%BD%AC%E5%88%97

 

Eg:

from pyspark.sql import Row
eDF = sqlContext.createDataFrame([Row(a=1, intlist=[1,2,3], mapfield={"a": "b"})])
eDF.select(explode(eDF.intlist).alias("anInt")).collect()
Out: [Row(anInt=1), Row(anInt=2), Row(anInt=3)]

 

来自 <http://spark.apache.org/docs/1.6.0/api/python/pyspark.sql.html?highlight=except#pyspark.sql.functions.exp>

 

Eg:

from pyspark.sql import Row

from pyspark.sql.functions import explode

eDF = spark.createDataFrame([Row(a=1, intlist=[1,2,3], mapfield={"a": "b"})])



eDF.show()

eDF.select(explode(eDF.intlist).alias("anInt")).show()

 

Eg:

df2=df1.select(explode(df1.line).alias("line_new_name")) 

 

 

eg:

### 将结果分割,并分裂为不同列

### 将结果分割,并分裂为不同列
df = df.withColumn('res', getLabel(df['data'])).withColumn("res2", explode(col('res')))   #getLabel为udf函数
df_split = df.withColumn("s", split(df['res2'], ",")) 
df_split = df_split.withColumn('id', df_split["s"].getItem(0)) 
df_split = df_split.withColumn('label', df_split["s"].getItem(1))

 

 

二、多列变一列

A . 拼接:

 

concat_ws(',',collect_list(concat(concat(concat(concat(rank,'@@'),lon),'@@'),lat))) as info

 

B .collect_list、collect_set

返回list,

collect_set去除重复元素;collect_list不去除重复元素

 

官方例子:

https://www.programcreek.com/python/example/98235/pyspark.sql.functions.collect_list

 

pyspark.sql.functions.collect_list(col) 不去重

Aggregate function: returns a list of objects with duplicates.

New in version 1.6.

pyspark.sql.functions.collect_set(col)去重

Aggregate function: returns a set of objects with duplicate elements eliminated

 

多列变一列并保持原顺序

collect_list不能保持原始的顺序,需要添加rank辅助列

拼接之后在使用的时候再split,不然直接split的话顺序就又乱了

eg: 

# 按rank排序后拼接
df_out =spark.sql('''
select cityid, 
    regexp_replace(
       concat_ws(',', 
             sort_array(
                    collect_list(  
                     concat_ws(  ':',
                                 lpad(cast(rank as string),2,'0'), 
                                 concat_ws("@@",concat_ws("@@", concat_ws("@@", concat_ws("@@", concat_ws("@@",poiid,poiname) ,lon),lat) ,hour),rank) 
                    )
                    )
              )  
        )
     , '\\[0-9]+\:',
     '')   
        
as line_string 
from  db.tablename where rank<100 group by id ''').distinct()
 

 

三、多行变一行

具体参考我另一篇博文

https://blog.csdn.net/sunflower_sara/article/details/104044463

 

用collect_set  或者 collect_list   + groupBy  二者相结合

collect_set去除重复元素;collect_list不去除重复元素

 

eg1:

spark.sql('''

select  businessid, businesstype,  collect_set(districtid) as list_districtid_tracepath from table

group By businessid, businesstype

''')

 

eg2:

 

 

附录:DataFrame添加新的一列

DataFrame添加新的一列

https://blog.csdn.net/sunflower_sara/article/details/104044176

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
可以使用pyspark的内置函数explode和getItem来实现将一列dict拆成多列的功能。 假设有一个DataFrame包含一列名为"info"的dict,如下所示: ```python from pyspark.sql.types import * from pyspark.sql.functions import * from pyspark.sql import SparkSession spark = SparkSession.builder.appName("example").getOrCreate() data = [("Alice", {"age": 25, "gender": "F"}), ("Bob", {"age": 30, "gender": "M"}), ("Charlie", {"age": 35, "gender": "M"})] schema = StructType([StructField("name", StringType(), True), StructField("info", MapType(StringType(), StringType()), True)]) df = spark.createDataFrame(data, schema) df.show() ``` 输出结果如下: ``` +-------+----------------+ | name| info| +-------+----------------+ | Alice|[age -> 25, gen...| | Bob|[age -> 30, gen...| |Charlie|[age -> 35, gen...| +-------+----------------+ ``` 现在需要将"info"列拆分成两列,分别为"age"和"gender",则可以使用以下代码: ```python df = df.select("name", explode("info").alias("key", "value")) df = df.select("name", col("key").alias("category"), col("value").alias("value")) df = df.pivot("name", "category", "value") df.show() ``` 其,第一行代码使用explode函数将"info"列拆分成两列"key"和"value",第二行代码将"key"列重命名为"category",将"value"列重命名为"value",第三行代码使用pivot函数将数据透视成需要的格式。 输出结果如下: ``` +-------+-----+------+ | name| age|gender| +-------+-----+------+ | Alice| 25| F| | Bob| 30| M| |Charlie| 35| M| +-------+-----+------+ ``` 可以看到,"info"列已经被成功拆分成了"age"和"gender"两列。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值