数据分析编程第二步: 最简单的数据分析尝试

2.1 数据介绍

有某公司的销售数据表 sales.csv 如下:

第一行标题,解释每一列存了什么东西。第二行开始每一行是一条数据,对应一个订单。

这种数据有个专业的术语,叫结构化数据。这是现代数据处理中最常见的数据类型。

整个表格的数据统称为一个数据表,其中的每一行(除了标题)称为一条记录,列称为字段,标题中的字符串称为字段名。上面这个表中能看见的部分有 12 条记录,对应着这个 Excel 的第 2 到第 13 行;有 8 个字段,字段名分别是 orderDate, sales, customer, product, quantity, price, discount, paymentDate。字段名互不相同,可以唯一地标识某个列。这些字段(包括名称和次序),称为数据表的数据结构,简称结构

结构化数据也就是有数据结构的数据。

表格中 A2:H13 部分就是数据表里的数据了。我们会说某条记录的某个字段的取值是什么。比如这里第 2 条记录的 sales 字段取值为 Hef,第 8 条记录的 quantity 字段取值为 8。数据表中每条记录的每个字段都会有一个取值。

注意,数据表中只有字段有名称,记录没有名称。我们后面会讲用什么办法来标识和区分记录。

可以有各种各样的数据表,不同数据表的数据结构当然可以不同。一个数据表一定要有一套数据结构,而且也只能有一套。有时我们也会说到记录的结构,意思就是指记录所在的数据表的结构。

因为结构化数据经常会以这种行列式表格的形式呈现,我们也会直观地把记录和字段称为,这是数据库界的通行术语,并不是我们发明的通俗说法。甚至,有时候数据表呈现出来时已经没有明显的行和列了(马上要讲到这样的例子),但人们仍然会用行和列这些术语来表示记录和字段。

本文档用到的 sales.csv 文件中列名的含义如下:

列名含义
orderID订单 ID,取值为自然数列,和记录序号一致
orderDate下单日期
sales销售
customer客户
product产品
quantity订单数量
price订单价格
discount订单折扣
paymentDate付款日期
feedBack客户反馈

2.2 选出去年的所有销售记录

第一步:读取 sales.csv 文件中的数据

A
1=file("sales.csv").import@tc()

A1 函数file("sales.csv")表示从主目录中找到 sales.csv 这个文件,并产生文件对象,这里参数是个字符串,要加双引号。import@tc()表示读入文件对象 file(“sales.csv”) 中的数据,这里@t是函数 import 的选项,表示文件的第一行是标题行,如果没有这个选项,会把第一行当成数据读入。@c表示文件中数据的列间分隔符是英文逗号,如果没有这个选项,会默认当成 tab 分隔符。当两个选项 @t 和 @c 同时写时,可以省略一个 @, 写成@tc

在界面中可以看到 A1 的值:

从图中可以看出 A1 的值是一个二维表。前面介绍过,sales.csv 文件中存储的是结构化数据,SPL 中用于装载结构化数据的对象称为序表,从名称上可以理解为有次序的二维表。上图中 A1 的值就是一个序表,从图上看,序表比原始的结构化数据多了一个 Index,这就是序表的记录次序,也称为记录序号,可以通过序号来访问序表中的某一条记录,比如 =A1(3),将返回 A1 中的第三条记录:

第二步:从 A1 中选出 2024 年下单的数据:

A
1=file(“sales.csv”).import@tc()
2=A1.select(year(orderDate)==2024)

A2 select 函数表示过滤,这里的过滤条件year(orderDate)==2024表示选出 orderDate 的年份等于 2024 的数据。在 SPL 中相等比较用==,而=表示赋值。year函数表示获得日期参数的年份。

界面上可以再看一下 A2 的值:

从界面上看,A2 是 2024 年的销售记录,表面上看和 A1 的序表似乎长得差不多,但它不是序表,它只是从 A1 序表中取出的部分记录组成的一个有序集合,在 SPL 中有个专门的名称叫排列

2.3 计算去年的总销售额、单笔最大订单额、订单个数

第一步:读取 sales.csv 文件中的数据

A
1=file(“sales.csv”).import@tc(orderDate,quantity,price,discount)

A1 由于本例中只用到了orderDate,quantity,price,discount这几个字段,所以可以在 import 函数参数中指定这几个字段,这样读数时只读这几个字段,可以提高读数效率,减少内存占用。

第二步:过滤出 2024 年的数据,并算出订单金额,以计算列的形式添加到原排列中

A
1=file(“sales.csv”).import@tc(orderDate,quantity,price,discount)
2=A1.select(year(orderDate)==2024).derive(quantity*price*discount:amount)

A2 derive 函数表示添加计算列,其中quantity*price*discount是计算表达式,amount是新产生的计算列的列名,表达式和列名之间用冒号分隔。特别强调的是表达式在前面,列名在后面。

第三步:聚合运算

A
1=file(“sales.csv”).import@tc(orderDate,quantity,price,discount)
2=A1.select(year(orderDate)==2024).derive(quantitypricediscount:amount)
3=A2.sum(amount)
4=A2.max(amount)
5=A2.count()

A3 对 A2 中的 amount 字段求和。

A4 对 A2 中的 amount 字段求最大值。

A5 对 A2 计数,算出 A2 的记录数。

2.4 选出金额最大的三个订单

A
1=file(“sales.csv”).import@tc()
2=A1.select(year(orderDate)==2024).derive(quantitypricediscount:amount)
3=A2.sort(-amount)
4=A3.to(3)

A3 sort 函数是排序,缺省是从小到大排,想从大到小排,相当于其相反数从小到大排,所以这里加了个负号,写成-amount

A4 A3.to(3)表示选出 A3 中的前三条记录。熟练之后可以把 A3 和 A4 写到一起:A2.sort(-amount).to(3)

A4 的结果为:

可以看出,这种算法虽然简单,但是没有解决排名并列的问题,对于可能存在并列的数据,SPL 还有个 top 函数可以处理:

A
1=file(“sales.csv”).import@tc()
2=A1.select(year(orderDate)==2024).derive(quantitypricediscount:amount)
3=A2.top@r(3;-amount)

A3 A2.top@r(3;-amount)表示将A2排序后取前 3 条记录。缺省排序规则和sort函数一致,但是top函数有个@r选项可以解决并列的情况。特别需要强调的是,3-amount之间是分号分隔,这时候返回的是排名前三的记录。如果写成逗号分隔,则返回排名前三的amount字段值。和 Excel 及其它程序语言不同,SPL 的参数分隔符不只是逗号,还可能有分号和冒号(在前面 derive 函数中就出现过冒号,用来分隔计算式和字段名)。

A3 的结果为:

top 函数解决了排名并列的问题。

2.5 第一笔付款的订单、最后一笔付款的订单

A
1=file(“sales.csv”).import@tc()
2=A1.select(year(orderDate)==2024)
3=A2.minp(paymentDate)
4=A2.maxp(paymentDate)

A3 A2.minp(ParmentDate)表示从排列 A2 中选出paymentDate的值最小的记录,这里用于选出第一笔付款的订单,它有点相当于 top(1,…)。由于本例中日期数据只精确到日,同一天可能存在多单付款,如果要把同一天付款的所有订单都选出,可以给 minp 函数加上@a选项,如:A2.minp@a(paymentDate)

A4 选出最后一笔付款的订单,maxp 函数规则和 minp 一致,这里不再赘述。

2.6 统计 2025 年 5 月 1 日以后下单的客户数和付款的客户数(去重)

AB
1=file(“sales.csv”).import@tc()2025-05-01
2=A1.select(orderDate>B1)
3=A2.icount(customer)
4=A2.select(paymentDate).icount(customer)

A3 A2.icount(customer)表示对A2逐行获得customer的值,并对结果进行去重计数。

A4 A2.select(paymentDate)表示选出paymentDate不为空的记录,即已付款记录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/94172.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/94172.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UDP报文的数据结构

主要内容参照https://doc.embedfire.com/net/lwip/zh/latest/doc/chapter14/chapter14.html#id6,整理出来自用。 1. UDP 报文首部结构体(udp_hdr) 为清晰定义 UDP 报文首部的各个字段,LwIP 设计了udp_hdr结构体,其包含…

图论与最短路学习笔记

图论与最短路在数学建模中的应用 一、图论模型图 G(V,E)G(V,E)G(V,E) VVV:顶点集合EEE:边集合每条边 (u,v)(u,v)(u,v) 赋予权值 w(u,v)w(u,v)w(u,v),可用 邻接矩阵 或 邻接表 表示。二、最短路问题的数学形式 目标:寻找从源点 sss…

第九节 Spring 基于构造函数的依赖注入

当容器调用带有一组参数的类构造函数时,基于构造函数的 DI 就完成了,其中每个参数代表一个对其他类的依赖。接下来,我们将通过示例来理解 Spring 基于构造函数的依赖注入。示例:下面的例子显示了一个类 TextEditor,只能…

【数据库】PostgreSQL详解:企业级关系型数据库

文章目录什么是PostgreSQL?核心特性1. 标准兼容性2. 扩展性3. 高级功能4. 可靠性数据类型1. 基本数据类型2. 高级数据类型基本操作1. 数据库操作2. 表操作3. 数据操作高级查询1. 连接查询2. 子查询3. 窗口函数JSON操作1. JSON数据类型2. JSON查询3. JSON索引全文搜索…

FFMPEG相关解密,打水印,合并,推流,

1:ffmepg进行打水印解密 前提ffmepg安装利用静态版就可以这个什么都有,不用再配置其他信息:(这个利用ffmpeg终端命令是没问题的,但是如果要是再C中调用ffmpeg库那么还需要从新编译安装下) 各个版本 Inde…

MySql知识梳理之DML语句

注意: 插入数据时,指定的字段顺序需要与值的顺序是一一对应的。 字符串和日期型数据应该包含在引号中。 插入的数据大小,应该在字段的规定范围内注意:修改语句的条件可以有,也可以没有,如果没有条件,则会修改整张表的所…

GaussDB GaussDB 数据库架构师修炼(十八)SQL引擎-SQL执行流程

1 SQL执行流程查询解析:词法分析、语法分析、 语义分析 查询重写:视图和规则展开、基于规则的查询优化 计划生成:路径搜索和枚举、选出最优执行计划 查询执行:基于优化器生成的物理执行计划对数据进行获取和计算2 解析器和优化器S…

grpc 1.45.2 在ubuntu中的编译

要在 Ubuntu 上编译 gRPC 1.45.2,需要按照以下步骤操作。以下指南基于 gRPC 官方文档和相关资源,确保环境配置正确并成功编译。请确保你有管理员权限(sudo)以安装依赖项和执行相关命令。 1. 准备环境 确保你的 Ubuntu 系统已安装…

lesson45:Linux基础入门指南:从内核到实践操作全解析

目录 一、Linux简介与核心概念 1.1 Linux的起源与发展 1.2 内核与发行版的关系 二、Linux内核版本解析 2.1 内核版本命名规则 2.2 2025年主流内核版本 三、主流Linux发行版对比 3.1 桌面用户首选 Ubuntu 24.04 LTS Linux Mint 22 3.2 技术爱好者之选 Fedora 41 Ar…

PCL点云库入门(第24讲)——PCL库点云特征之NARF特征描述 Normal Aligned Radial Feature(NARF)

一、算法原理 1、NARF 特征概述 NARF(Normal Aligned Radial Feature)是 2011 年由 Bastian Steder 等人在论文 《Point Feature Extraction on 3D Range Scans Taking into Account Object Boundaries》中提出的一种 稀疏局部 3D 特征描述子。 核心目标是提取具有“边界意…

使用 eventpp 构建跨 RT-Thread 与 ARM-Linux 的轻量级 Active Object(AO)事件驱动框架

0. 引言 本文展示一个实践路径:以轻量级 C 事件库 eventpp 为核心,设计并实现一个面向嵌入式的、可移植的 Active Object(AO)事件驱动架构。该架构满足以下目标: 跨平台兼容:单套代码在 RT-Thread&#xff…

【python实用小脚本-193】Python全能PDF小助手:剪切/合并/旋转/加密一条龙——再也不用开会员

Python全能PDF小助手:剪切/合并/旋转/加密一条龙——再也不用开会员 PDF编辑, 本地处理, 零会员费, 多功能脚本, 瑞士军刀 故事开场:一把瑞士军刀救了周五下班的你 周五 17:55,老板甩来一堆 PDF: “把第 3、7 页删掉”“再和合同合…

Ubuntu根分区扩容

目录 1.先查看/dev/sda 整块磁盘设备的分区占用情况: 2.在VMware中编辑虚拟机: 3.进入虚拟机,进入disk应用程序: 4.扩容文件系统 5.最后通过df-h lsblk或通过可视化GParted进行验证。 1.先查看/dev/sda 整块磁盘设备的分区占…

智慧城市SaaS平台/市政设施运行监测系统之空气质量监测系统、VOC气体监测系统、污水水质监测系统及环卫车辆定位调度系统架构内容

1. 空气质量监测系统1) 监测点管理 a) 监测点基本信息 支持记录空气质量监测点的名称、位置、类型、设备配置等信息。 b) 监测点分布地图 支持通过GIS地图展示监测点的分布情况,支持地图查询和导航。 2) 空气质量监测 a) 实时数据采集 支持实时采集空气质量数据&…

PiscCode迅速集成YOLO-Pose 实现姿态关键点轨迹跟踪应用

在计算机视觉领域,人体姿态检测与轨迹跟踪是很多应用场景的核心技术,例如运动分析、行为识别、智能监控等。本文将介绍如何在 PiscCode 平台上,利用 YOLO-Pose 模型进行姿态估计,并实现多人关键点轨迹跟踪。 一、什么是 PiscCode …

HTTP的状态码有哪些,并用例子说明一下

问题HTTP的状态码有哪些,并用例子说明一下我的回答HTTP状态码是服务器对客户端请求的响应码,它们按照不同的功能被分为五大类。我来介绍一下主要的状态码及其实际应用场景:1xx(信息性状态码):表示请求已接收…

【51单片机】【protues仿真】基于51单片机宠物投食器系统

目录 一、主要功能 二、使用步骤 三、硬件资源 四、软件设计 五、实验现象 一、主要功能 1、LCD1602液晶显示当前时间 2、按键设置时间,5个定时投喂时间​ 3、可以通过手动按键进行投喂食物 4、步进电机模拟投喂食物 二、使用步骤 基于51单片机的宠物自动投…

掌握设计模式--命令模式

命令模式(Command Pattern) 命令模式(Command Pattern)是一种行为型设计模式,它将请求(命令)封装成对象,从而使您能够参数化客户端(调用者)使用不同的请求、…

STM32之beep、多文件、延迟、按键以及呼吸灯

一、Beep控制 原理图分析: 蜂鸣器三极管控制引脚对应 MCU PB8。当前蜂鸣器对应的电路中,三极管是 NPN 三极管,当前【基极】存在小电流,当前三极管导通。要求对应 PB8 引脚对外输出电压 / 电流。当前 PB8 输出高电平,当…

C++的struct里面可以放函数,讨论一下C++和C关于struct的使用区别

我们来看一个C代码下面的struct结构体: struct UserValue {float lx;float ly;float rx;float ry;float L2;// 【构造函数】UserValue() {setZero();}// 【成员函数】void setZero() {lx 0;ly 0;rx 0;ry 0;L2 0;} };在这篇文章中,我们将来详细解释一下为什么 U…