使用 spark python 拆分数据帧

Posted

技术标签:

【中文标题】使用 spark python 拆分数据帧【英文标题】:Splitting dataFrame using spark python 【发布时间】:2017-10-16 15:07:33 【问题描述】:

我在 spark 中使用数据框以表格格式拆分和存储数据。我在文件中的数据如下所示 -

"click_id": 123, "created_at": "2016-10-03T10:50:33", "product_id": 98373, "product_price": 220.50, "user_id": 1, "ip": "10.10.10.10"
"click_id": 124, "created_at": "2017-02-03T10:51:33", "product_id": 97373, "product_price": 320.50, "user_id": 1, "ip": "10.13.10.10"
"click_id": 125, "created_at": "2017-10-03T10:52:33", "product_id": 96373, "product_price": 20.50, "user_id": 1, "ip": "192.168.2.1"

我已经编写了这段代码来拆分数据 -

from pyspark.sql import Row
from pyspark.sql import SparkSession
from pyspark.sql import SQLContext
import pyspark.sql.functions as psf

spark = SparkSession \
    .builder \
    .appName("Hello") \
    .config("World") \
    .getOrCreate()

sc = spark.sparkContext
sqlContext = SQLContext(sc)

ratings = spark.createDataFrame(
    sc.textFile("transactions.json").map(lambda l: l.split(',')),
    ["Col1","Col2","Col3","Col4","Col5","Col6"]
)

ratings.registerTempTable("ratings")

final_df = sqlContext.sql("select * from ratings");
final_df.show(20,False)

上面的代码运行良好,输出如下:

从输出中可以看出,"click_id and number" 正在显示,created_at and timestamp 也正在显示。

我希望实际上只有表中的值 - click_id、created_at、product_id 等等。

如何只将这些值放入我的表中?

【问题讨论】:

您的意思是,删除键(click_id, created_at 等)并只保留所有 6 列的值? @desertnaut 是的 【参考方案1】:

在你的 map 函数中,解析 json 对象而不是拆分它

map(lambda l: l.split(','))

应该变成

map(lambda l: json.loads(l))

(导入 json 后)

import json

如果你删除列定义

["Col1","Col2","Col3","Col4","Col5","Col6"]

您将从 json 中获取列

【讨论】:

【参考方案2】:

假设您只想使用数据帧 API,那么您可以使用以下代码:

ratings = spark.read.json("transactions.json")

这会将 json 加载到数据框中,将 json 键映射到列名。 然后,您可以使用以下代码选择并重命名列。

ratings = ratings.select(col('click_id').alias('Col1'),
                         col('created_at').alias('Col2'),
                         col('product_id').alias('Col3'),
                         col('product_price').alias('Col4'),
                         col('user_id').alias('Col5'),
                         col('ip').alias('Col6'))

通过这种方式,您还可以将列转换为相关的数据类型,例如col('product_price').cast('double').alias('Col4') 并正确保存到数据库。

【讨论】:

有没有办法将单个列名存储为列表并将每个值作为参数传递? 如果我理解正确你的意思,你可以有一个数组,例如arr = ["Col1","Col2","Col3","Col4","Col5","Col6"]df = df.select(arr) 例如 - 我想将 click_id 存储到列表/数组中,并将这些值中的每一个 arr[0]、arr[1] 传递给将 click_id 作为输入参数的函数 get_value(click_id) @geopet 你可以试试df.select('click_id').rdd.flatMap(lambda x: x).collect(),它会生成一个包含所有click_id值的数组,可以随意处理。

以上是关于使用 spark python 拆分数据帧的主要内容,如果未能解决你的问题,请参考以下文章

使用行分隔符拆分 Spark 数据帧

Spark中的拆分,操作和联合数据框

Spark 从超级数据帧优化方法生成子数据帧

如何根据原始数据帧中的总行数将数据帧拆分为两个数据帧

使用 Python 将 Dask 数据帧转换为 Spark 数据帧

Databricks:如何将 %python 下的 Spark 数据帧转换为 %r 下的数据帧