python模拟生成数据、scala-spark处理数据(简单应用)

文章介绍了如何使用Scala和Spark进行数据处理,包括使用Python生成随机数据、将数据保存为行格式的JSON,以及利用SparkSQL进行基本数据分析。作者还提到了IDEA和Python在项目中的应用。
摘要由CSDN通过智能技术生成

内容简介:用scala语言,利用spark算子及sparksql来对特定数据进行处理
用到的东西:IDEA、Spark、scala、python
该文章为期末作业,仅供参考

一、数据源

对特定数据分析的前提是有满足条件的数据集,但是一般很难找到符合符合自己需求的数据集,这个时候可以选择自己模拟生成一些随机的数据,毕竟此次只为作业,对数据集的要求并不严格。

一、1.利用python随机生成数据

import random
import string
import pandas as pd
from datetime import datetime, timedelta

# 生成随机产品型号
def generate_product_model():
    return random.choice(['L100', 'L200', 'L300', 'L400'])

# 生成指定时间格式的随机日期
def generate_specific_random_date(start_date, num_rows):
    current_date = start_date.replace(hour=8, minute=30, second=0, microsecond=0)
    date_list = [current_date]
    for _ in range(num_rows - 1):
        current_date += timedelta(minutes=0.5)
        date_list.append(current_date)
    return date_list

# 生成随机产品生产批次
def generate_production_batch(length=5):
    return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length))

# 生成随机产品生产数量
def generate_production_quantity():
    return random.randint(1, 1000)

# 生成是否测试生产
def generate_testing_status(quantity):
    return quantity < 50

# 生成次品生产数
def generate_defective_quantity():
    if random.random() < 0.9:
        return []
    else:
        return [random.randint(1, 10) for _ in range(random.randint(1, 5))]

# 生成几号流水线
def generate_pipeline_number():
    return random.choice(['K1', 'K2', 'K3','K4','K5','K6'])
    

# 控制生成行数
num_rows = 1441

# 生成数据
start_date = datetime(2023, 11, 14)
random_dates = generate_specific_random_date(start_date, num_rows)

data = {
    #流水线编号
    'assemblyLine_number': [generate_pipeline_number() for _ in range(num_rows)],
    #产品型号
    'productNumber': [generate_product_model() for _ in range(num_rows)],
    #生产批次
    'ProductionLot' : [generate_production_batch() for _ in range(num_rows)],
    #生产日期
    'productionDate': [date.strftime('%Y-%m-%d %H:%M:%S') for date in random_dates],
    #生产数量
    'productionQuantity': [generate_production_quantity() for _ in range(num_rows)],
    #次品生产数量
    'defectiveProductionQuantity' : [generate_defective_quantity() for _ in range(num_rows)]
}

# 创建表格对象
df = pd.DataFrame(data)
df['testProduction'] = [generate_testing_status(qty) for qty in data['productionQuantity']]
df

这里展示的是利用python来随机生成数据并保存为表格对象的源码,图里利用到了python的一些库,并封装成函数方便表格对象创建时候的调用。
生成数据如下:
随机生成数据集效果

一、2.将python的表格对象保存为本地json文件

因为spark读取json的特殊性,json文件格式必须为行存储,即一行为一条json格式的数据,没有换行符。所以必须在保存的时候就做好换行处理。其实不用换行处理用逗号隔开也是可以的,但是后期就要花更多的功夫去兼容。
每行为一条json格式的数据
这里介绍一下python的一个三方库jsonlines,它可以很好把一个表格对象直接转成行存储的json文件。jsonlines参考使用来自这里
之后我们在python里使用jsonlines将我们的表格对象转为json格式的文件。

import jsonlines
with jsonlines.open('2023-11-14.data.json', mode='w') as writer:
    for i in range(df.index.stop):
        json_data = dict(df.iloc[i])
        json_data["productionQuantity"] = int(json_data["productionQuantity"])
        json_data["testProduction"] = bool(json_data["testProduction"])
        writer.write(json_data)

首先循环提取表格对象的每一行数据并打包成字典然后写入json文件,不会存在换行符。这里的表格对象也可以直接使用上述数据生成代码里的data,即生成表格对象的原始字典。这一步需要注意的是,jsonlines无法转换数据中包含numpy数据类型的对象,如果你的数据对象里的整数是numpy.int64类型的,那么他会报错。

二、利用scala对数据进行分析

二、1.sparksql

根据需求对数据进行分析,我自己写了一个指标说明文档,这里就不列出。直接展示代码,这里展示了用sparksql来对数据进行一个聚合。

package com.dzk.Job

import org.apache.spark.sql.functions.desc
import org.apache.spark.sql.{DataFrame, SparkSession}

object a_assemblyLine_number_productionQuantity {
  def main(args: Array[String]): Unit = {
    val ss: SparkSession = new SparkSession.Builder().appName("demo").master("local").getOrCreate()
//    val df: DataFrame = ss.read.json("hdfs://20210322005-master:9000/2023-11-14.data.json")
    val df: DataFrame = ss.read.json("2023-11-14.data.json")
    df.groupBy("assemblyLine_number")
      .sum("productionQuantity")
      .withColumnRenamed("sum(productionQuantity)","流水线sum")
      .orderBy(desc("流水线sum"))
      .show()
  }//main
}//object

这里简单的写了一个sparksql来完成我的需求,他将某两列进行一个聚合,为我展示出各个流水线生产出的总产品数量
sparksql运行代码效果

二、2.sparkRDD

下面还利用RDD的算子来对数据进行一个更复杂的运算,这是sql做不到的。
需求:计算某流水线的交货数,交货数=生产总数-次品书(数组形式存储数值,计算总和得计算该数组元素总和)-样品数(生产数小于50的为测试生产,即样品)

package com.dzk.Job

import com.google.gson.Gson
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object c_assemblyLine_number_defectiveProductionQuantity {
  def main(args: Array[String]): Unit = {
    val conf: SparkConf = new SparkConf().setAppName("demo").setMaster("local")
    val sc: SparkContext = new SparkContext(conf)
//    val rdd: RDD[String] = sc.textFile("hdfs://20210322005-master:9000/2023-11-14.data.json")
      val rdd: RDD[String] = sc.textFile("2023-11-14.data.json")

    rdd.map(
      data => {
        val value: getClass = new Gson().fromJson(data, classOf[getClass])
        value
      }
    )
    .groupBy(x => x.assemblyLine_number)
    .map(x=>{
    var total = 0
    for( one <- x._2 ){
      total = total+one.defectiveProductionQuantity.sum
    }
    (x._1,total);
    })
    .sortBy(x => x,ascending = false)
    .collect()
    .foreach(x => println(x))
  }//main
}

还有几个指标就不一一说明,该次任务只用到了sparksql以及sparkRDD来对数据进行处理。

三、总结

使用IDE

IDEA、VSCODE

使用语言

scala、python

过程感受

通过这次业务,你可以简要了解一个数据分析的业务的步骤,比如数据获取,数据处理,数据分析,还有指标说明文档,字段说明文档,以及模拟生成数据如何贴近现实。了解s如何利用python生成随机数据,如何将数据保存为行存储的json文件,scala以及sparksql的简单用法。

python按行写入json文件,每一行都是一个标准json对象,但是整体文件却非json对象:https://blog.csdn.net/Together_CZ/article/details/130963028

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值