项目六 动态网页数据预处理

pandas 的 Series/DataFrame、缺失值处理、分组统计,以及 Pig 的批量处理写法。

预处理第11-13周pandas · Pig25 段代码

本项目学习目标

  • 能读写 CSV/Excel,查看与切选数据
  • 能处理缺失值、重复值、异常值
  • 能做分组聚合与描述统计
  • 能用 Pig Latin 完成简单的批处理

本项目任务导览

01

动态网页数据预处理

使用 Pandas 实现新闻动态网页数据预处理、使用 Pig 实现浪潮云说网页数据预处理、使用 ELK 实现某官网日志数据预处理。

  • 项目导言与学习目标
  • 任务 6-1 使用 Pandas 实现新闻动态网页数据预处理
  • 任务 6-2 使用 Pig 实现浪潮云说网页数据预处理
  • 任务 6-3 使用 ELK 实现某官网日志数据预处理
  • 知识拓展与实例案例(3 例)
项目导言与学习目标

原始数据往往"脏、乱、差",预处理是数据分析的前置保障。

数据预处理是指将数据的缺失值、脏数据、数据格式等进行调整处理。由于数据采集过程中会因为数据的来源不统一造成数据格式的混乱,当使用这些原始数据进行数据分析时无法为决策提供有效的帮助,对数据进行预处理能够有效解决这些问题。

了解什么是数据预处理; 熟悉数据预处理的方法; 掌握 Pandas、Pig 以及 ELK 进行数据预处理的方法; 精通 Pig 以及 ELK 环境搭建方法。

具备了解 Pandas 和 Pig 数据预处理的能力; 具备熟悉 Pandas 和 Pig 数据预处理机制的能力; 具备掌握 Pandas 和 Pig 数据预处理方法的能力; 具备掌握 ELK 数据预处理方法及流程的能力; 具备精通数据预处理的能力。

具备团队意识; 具备良好的解决问题的能力; 具备较强的学习能力。

03

任务 6-1 使用 Pandas 实现新闻动态网页数据预处理

目录:Pandas 简介及安装 → 数据结构 → 基本功能 → 汇总和描述统计 → 处理缺失数据。

一、Pandas 简介及安装

Pandas 是 Python 的核心开源数据分析支持库。Pandas 是基于 NumPy 开发用于完成数据分析开发的数据分析工具,并且纳入了大量的库和标准数据模型,为实现高效的大型数据集操作提供支持。

二、Pandas 数据结构

三、Pandas 基本功能

该方法用于从 CSV 文件中读取数据,其必要参数为数据文件的存储路径,同时还可在读取文件时设置分隔符、编码、进行空值定义等操作。

PYTHON
pd.read_csv(filepath_or_buffer, sep=',', header='infer', names=None, index_col=None,
            prefix=None, dtype=None, encoding=None, converters=None,
            skipinitialspace=False, na_values=None, na_filter=True,
            true_values=None, false_values=None)
参数描述
filepath_or_buffer文件路径
sep分隔符设置,默认值为','
header数据文件中用于表示列名部分的行数(数据开始的行),默认为 0
names用于为结果添加列名
index_col指定索引列
prefix自动生成的列名编号的前缀
dtype指定列的数据类型
encoding指定编码
converters设置指定列的处理函数,可以用"序号"、"列名"进行列的指定
skipinitialspace忽略分割符后面的空格
na_values空值定义
na_filter检测空值,值为 False 时可以提供大文件的读取性能
true_values将指定文本转换为 true
false_values将指定文本转换为 false

该方法主要用于从 Excel 文件中加载数据并以二维数据表的格式输出。

PYTHON
pd.read_excel(io, sheet_name=0, header=0, names=None, index_col=None, usecols=None,
              squeeze=False, dtype=None, true_values=None, false_values=None,
              skiprows=None, nrows=None)
参数描述
io文件路径
sheet_name指定表单名称
header设置数据中为表头的行,默认为 0
names自定义表头的名称,值为数组类型
index_col指定作为索引的列
usecols设置要获取的列的范围。值为 str,则表示 Excel 列字母和列范围的逗号分隔列表;为 int,则表示解析到第几列;为 int 列表,则表示解析列表中指定的列
squeeze默认为 False。设置 squeeze=True 时表示如果解析的数据只包含一列,则返回一个 Series
dtype指定列的数据类型,默认为 None 不改变数据类型
true_values将指定的文本转换为 True,默认为 None
false_values将指定的文本转换为 False,默认为 None
skiprows省略指定行数的数据
nrows指定需要读取前多少行,通常用于较大的数据文件中

该方法主要用于从 SQL 数据库表获取数据,该方法需要创建与数据库的链接,通过 SQL 语句从表中获取数据。

PYTHON
pandas.read_sql(sql, con, index_col=None, coerce_float=True, parse_dates=None,
                columns=None, chunksize=None)
参数描述
sql用于查询数据的 sql 语句,类型为 str
con连接数据所需的引擎,使用对应的数据库链接库创建
index_col选择某一列作为 index
coerce_float将数字形字符串转为 float 读入
parse_dates将某一列日期型字符串转换为 datetime 型数据
columns要选取的列
chunksize指定输出的行数

该方法用于加载 JSON 文件中的数据,与 read_csv() 和 read_excel() 使用方法一致。

PYTHON
pd.read_json(path_or_buf=None, orient=None, typ='frame', dtype=True,
             keep_default_dates=True, numpy=False, date_unit=None,
             encoding=None, lines=False)
参数描述
path_or_buf文件路径
orient指示预期的 JSON 字符串格式
typ要恢复的对象类型
dtype指定数据类型,值为 json、dict
keep_default_dates是否保留默认日期处理
numpy直接解码为 numpy 数组
date_unit用于检测转换日期的时间戳单位
encoding指定编码
lines按行读取文件作为 json 对象

Pandas 中提供了若干用于检查数据信息的方法,如维度、基本信息、空值、列名等相关信息,能够帮助我们快速了解数据的基本信息,主要应用在数据量较大无法快速获取有效信息的情况。

属性和方法描述
DataFrame.shape()查看数据的维度
DataFrame.dtypes()每列数据的格式
DataFrame.values()查看数据表的值
DataFrame.columns()查看数据列名称
DataFrame.info()查看数据表基本信息
DataFrame.isnull()查看空值
DataFrame.unique()查看某一列的唯一值
DataFrame.head()查看前指定行数据,默认为 10
DataFrame.tail()查看后指定行数据,默认为 10

该方法用于将 Pandas 程序中的数据持久化保存到 csv 文件中。

PYTHON
DataFrame.to_csv(path_or_buf=None, sep=',', na_rep='', float_format=None,
                 columns=None, header=True, index=True, index_label=None,
                 mode='w', encoding=None)
参数描述
path_or_buf字符串类型的文件路径对象
sep输出文件的字段分隔符
na_rep缺失数据填充
float_format小数点保留几位,参数类型为字符串
columns自定义列名,参数类型为序列或数组
header写出列名,若给定字符串列表,则作为列名的别名
index写入索引,默认为 true
modePython 写入模式,默认为"w"。w: 覆盖写入;a: 追加写入;r+: 可读可写,必须存在;w+: 可读可写,可以不存在,必会擦掉原有内容从头写;a+: 可读可写,可以不存在,必不能修改原有内容,只能在结尾追加写
encoding表示输出文件中使用的编码的字符串,默认为"utf-8"

该方法用于将 DataFrame 数据以 Excel 表格的形式保存到本地文件系统。

PYTHON
DataFrame.to_excel(excel_writer, sheet_name='Sheet1', na_rep='',
                   float_format=None, columns=None, header=True, index=True,
                   startrow=0, startcol=0)
参数描述
excel_writer保存到的文件路径
sheet_name保存的 sheet 名
na_rep缺失数据表示方式,默认为空
float_format格式化浮点数的字符串,默认为 None
startrow保存的数据在目标文件的开始行
startcol保存的数据在目标文件开始的列
header显示列名
columns自定义列名
index是否显示索引

在使用 Pandas 处理 Json 类型的数据时通常会将 Json 数据加载到程序中转换为 DataFrame(可使用 read_json),在处理完成后需要将处理后的数据保存回 Json,这时就需要用到 to_json() 方法。

PYTHON
DataFrame.to_json(path_or_buf=None, orient=None, date_format=None,
                  double_precision=10, force_ascii=True, date_unit='ms',
                  default_handler=None, lines=False, compression=None, index=True)
参数描述
path_or_buf指定文件保存路径
orient指定为将要输出的 JSON 格式
date_format日期转换类型
double_precision对浮点值进行编码时使用的小数位数,默认为 10 位
force_ascii强制编码为 ASCII
index是否包含索引值

to_sql() 是 Pandas 中提供的用于将 DataFrame 数据保存到数据库的 API。

PYTHON
DataFrame.to_sql(name, con, schema=None, if_exists='fail', index=True,
                 index_label=None, chunksize=None)
参数描述
name表名称
con连接 sql 数据库的 engine,可以用 pymysql 之类的包建立
schema相应数据库的引擎,不设置则使用数据库的默认引擎,如 mysql 中的 innodb 引擎
index是否将表中索引保存到数据库
index_label是否使用索引名称
if_exists当数据库表存在时,设置数据的保存方式
chunksize批量保存数据量大小

四、汇总和描述统计

Pandas 提供了一组常用的汇总和描述统计方法,用于数据分析中完成汇总统计的功能。与对应的 NumPy 数组方法相比,它们都是基于没有缺失数据的假设而构建的。

函数描述
df.sum()求和函数
df.mean()求平均值
df.min() / df.max()求最小值和最大值。对于字符串类型的,最小值返回按字母升序;当不忽略 null 值时,最小值最大值都是 NaN
df.var()求样本值的方差
df.std()求样本值的标准差
df.count()计算非 null 值的数量
df.median()计算中位数

五、处理缺失数据

缺失值是指数据中由于某些信息的缺失,造成现有数据中某个或某些属性不完整。Pandas 中提供了若干对缺失值处理的方法,可分为四类:缺失值判断、缺失值统计、缺失值填充、缺失值删除。

PYTHON
df.isna()
PYTHON
df.isna().sum(axis=None)
PYTHON
df.fillna(value=None, method=None, axis=None,
          inplace=False, limit=None, downcast=None)
PYTHON
df.dropna(axis=None)
04

任务 6-2 使用 Pig 实现浪潮云说网页数据预处理

Pig 是基于 Hadoop 的大规模数据分析平台,用 Pig Latin 语言以数据流方式处理数据。

一、Pig 简介

Pig 是一款基于 Hadoop 的大规模数据分析平台,是 Apache 平台下的免费开源项目,是 MapReduce 的一个抽象。它是一个工具/平台,用于分析较大数据集,并表示为数据流。Pig 通常与 Hadoop 一起使用。

二、Pig 配置运行

PYTHON
# 配置环境变量 ~/.bashrc
[root@master local]# vim ~/.bashrc
export PIG_HOME=/usr/local/pig
export PATH=$PATH:$PIG_HOME/bin
export PIG_CLASSPATH=$HADOOP_HOME/etc/hadoop
[root@master local]# source ~/.bashrc
[root@master local]# pig -version

三、Pig Latin 执行

Apache Pig 提供了本地模式和 MapReduce 模式两种运行模式。在 Local 模式下,所有文件都从本地主机和文件系统中安装和运行,不需要使用 Hadoop 或 HDFS,此模式多用于测试。MapReduce 模式是使用 Apache Pig 加载或处理 Hadoop 的分布式文件系统(HDFS)中存储的数据。

四、运算符

比较运算符用于对符号两边的值进行比较,返回值有两种情况即 True 或 False。

运算符描述
==等于,检查两个数的值是否相等;如果是,则条件为 true
!=不等于,检查两个数的值是否相等。如果值不相等,则条件为 true
>大于,检查左边数的值是否大于右边数的值,如果是,则条件变为 true
<小于,检查左边数的值是否小于右边数的值,如果是,则条件变为 true
>=大于或等于,检查左边数的值是否大于或等于右边数的值,如果是,则条件变为 true
<=小于或等于,检查左边数的值是否小于或等于右边数的值,如果是,则条件变为 true
matches模式匹配,检查左侧的字符串是否与右侧的常量匹配

Pig Latin 的类型结构运算符主要有三个:元组构建运算符、包构造函数运算符和映射构造函数运算符。

运算符描述示例
()元组构造函数运算符 - 此运算符用于构建元组(Raju, 30)
{}包构造函数运算符 - 此运算符用于构造包{(Raju,30),(Mohammad,45)}
[]映射构造函数运算符 - 此运算符用于构造一个映射[name#Raja, age#30]

LOAD 加载数据:LOAD 运算符由两部分构成,使用等号(=)分割,等号左侧需要指定存储数据的关系的名称,右侧需要定义存储数据的方式。

PYTHON
Relation_name = LOAD 'Input file path' USING function as schema;
参数说明
relation_name设置数据保存目标关系名称
Input file path数据文件在本地或 HDFS 的存储路径
function设置加载数据的文件类型函数
Schema数据模式,加载数据时必须指定数据模式(列名)

STORE 存储数据:数据处理场景中,数据的体量通常会超过数十万条,仅靠程序的标准输出不能满足阅读条件,并且若要对处理后的数据进一步应用还要将其进行持久化存储。

PYTHON
STORE Relation_name INTO 'required_directory_path' [USING function];
参数说明
Relation_name关系名
required_directory_path关系目标存储路径
USING function加载函数
运算说明示例
Dump用于运行 Pig Latin 语句,并将结果打印到屏幕显示,此方法通常用于测试Dump student;
Describe用于查看关系的模式describe student;
explain用于显示关系的逻辑、物理和 MapReduce 执行计划explain student;
illustrate能够输出各语句逐步执行的结果illustrate student;

分组操作在 SQL 中使用频率很高,Pig Latin 中同样提供了对数据进行分组方法,Group 运算符能够对一个或多个关系中的数据进行分组。

PYTHON
# 对单个关系分组
Group_data = GROUP Relation_name BY Group_key;
# 对多个关系分组
Group_data = GROUP Relation_name1 BY Group_key, Relation_name2 BY Group_key;
参数说明
Relation_name关系名
Group_key分组 key

连接运算操作类似 SQL 中的关联查询。在执行一个数据处理任务时,通常数据文件会保存在多个数据集中,这时就需要使用连接操作;或两个数据集中存在一定的联系,需要联合处理。Pig Latin 中的连接运算需要从每个关系中声明一个或一组元组作为 key,当这些 key 匹配时,两个特定的元组匹配,否则记录将被丢弃。连接可以是以下类型:自连接、内部连接和外连接。

PYTHON
# 自连接
Relation_name = JOIN Relation1_name BY key, Relation2_name BY key;

# 内部连接
result = JOIN relation1 BY columnname, relation2 BY columnname;

# 左外连接
outer_left = JOIN relation1 BY columnname LEFT, relation2 BY columnname;

# 右外连接
outer_right = JOIN relation1 BY columnname RIGHT, relation2 BY columnname;

# 全外连接
outer_full = JOIN relation1 BY columnname FULL OUTER, relation2 BY columnname;

五、内置函数

Eval 函数能够对数据进行简单的统计运算,如平均值、最大值、最小值、求和等操作。

函数描述
AVG()计算平均值
BagToString()将包的元素连接成字符串。在连接时,可以在这些值之间放置分隔符(可选)
CONCAT()连接两个或多个相同类型的表达式
COUNT()统计元素数量
MAX()计算最大值
MIN()计算最小值
SIZE()基于任何 Pig 数据类型计算元素的数量
SUM()要获取单列包中某列的数值总和

字符串函数主要用于对数据中字符类型的数据进行处理,如大小写转换、截取字符、字符比较等。

函数描述
ENDSWITH(string, testAgainst)验证字符串是否以特定字符结尾
STARTSWITH(string, substring)验证第一个字符串是否以第二个字符串开头
SUBSTRING(string, startIndex, stopIndex)返回来自给定字符串的子字符串
EqualsIgnoreCase(string1, string2)比较两个字符串,忽略大小写
INDEXOF(string, 'character', startIndex)返回字符串中指定的第一个出现的字符
LAST_INDEX_OF(expression)返回字符串中指定的最后一个出现的字符
LCFIRST(expression)将字符串中的第一个字符转换为小写
UCFIRST(expression)将字符串中的第一个字符转换为大写
UPPER(expression)将字符串中的所有字符转换为大写
LOWER(expression)将字符串中的所有字符转换为小写
REPLACE(string, oldChar, newChar)使用新字符替换字符串中的现有字符
STRSPLIT(string, regex, limit)通过给定分隔符拆分字符串
TRIM(expression)去掉字符串头尾空格
LTRIM(expression)去掉字符串开头空格
RTRIM(expression)去掉字符串尾部空格

日期函数用于对日期类型的数据进行处理,如获取时间中的年、月、日、时、分、秒等内容。

重载方式描述
ToDate(milliseconds)接收毫秒时间,转换为日期时间对象
ToDate(iosstring)接收字符串类型的时间,并转换为日期时间对象
ToDate(userstring, format)userstring 代表用户输入的时间字符串,format 用于指定用户输入的日期时间的格式,如 ToDate('1990/12/19 03:11:44', 'yyyy/MM/dd HH:mm:ss'),结果返回 1990-12-19T03:11:44.000+05:30
ToDate(userstring, format, timezone)该方式较上一种可多设置一个时区
函数描述
ToDate(datetime)根据给定的参数返回日期时间对象
GetDay(datetime)返回时间对象中的某一天
GetHour(datetime)返回时间对象中的小时
GetMilliSecond(datetime)返回时间对象中的毫秒
GetMinute(datetime)从日期时间对象返回一小时中的分钟
GetMonth(datetime)返回时间对象中的月份
GetSecond(datetime)从返回时间对象中的秒
GetWeek(datetime)从日期时间对象返回一年中的周
GetYear(datetime)从日期时间对象返回年份
DaysBetween(enddatetime, startdatetime)返回两个日期时间对象之间的天数
HoursBetween(enddatetime, startdatetime)返回两个日期时间对象之间的小时数
MilliSecondsBetween(datetime1, datetime2)返回两个日期时间对象之间的毫秒数
MinutesBetween(datetime1, datetime2)返回两个日期时间对象之间的分钟数
MonthsBetween(datetime1, datetime2)返回两个日期时间对象之间的月数
SecondsBetween(datetime1, datetime2)返回两个日期时间对象之间的秒数
WeeksBetween(datetime1, datetime2)返回两个日期时间对象之间的周数
YearsBetween(datetime1, datetime2)返回两个日期时间对象之间的年数
函数描述
ABS(expression)获取表达式的绝对值
ACOS(expression)获得表达式的反余弦值
ASIN(expression)获取表达式的反正弦值
ATAN(expression)此函数用于获取表达式的反正切值
CBRT(expression)此函数用于获取表达式的立方根
CEIL(expression)此函数用于获取向上舍入到最接近的整数的表达式的值(近 1 取整)
COS(expression)此函数用于获取表达式的三角余弦值
COSH(expression)此函数用于获取表达式的双曲余弦值
EXP(expression)此函数用于获得欧拉数 e 乘以 x 的幂,即指数
FLOOR(expression)要获得向下取整为最接近整数的表达式的值(四舍五入取整)
LOG(expression)获得表达式的自然对数(基于 e)
LOG10(expression)得到表达式的基于 10 的对数
RANDOM()获得大于或等于 0.0 且小于 1.0 的伪随机数(double 类型)
ROUND(expression)要将表达式的值四舍五入为整数(如果结果类型为 float)或四舍五入为长整型(如果结果类型为 double)
SIN(expression)获得表达式的正弦值
SINH(expression)获得表达式的双曲正弦值
SQRT(expression)获得表达式的正平方根
TAN(expression)获得角度的三角正切
TANH(expression)获得表达式的双曲正切
05

任务 6-3 使用 ELK 实现某官网日志数据预处理

ELK = Elasticsearch + Logstash + Kibana,是日志数据采集、处理与可视化的经典技术栈。

一、Elasticsearch

Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,使用 Java 语言开发,由 Elastic 公司创建并开源维护的,并且作为 Apache 的开源项目,在云计算方面能够提供稳定、可靠、快速的实时搜索服务。Elasticsearch 支持多种语言的编程接口,比如 Java、.NET(C#)、PHP、Python、Apache Groovy 等。

  • 将安装包上传到 Linux 系统中的 /usr/local 目录下,为 Elasticsearch 创建安装用户名为"es";
  • 在 root 用户下解压 elasticsearch 安装包,为 es 用户设置对 elasticsearch 的权限;
  • 进入 elasticsearch-6.1.0 目录修改 elasticsearch.yml,使任何主机都能够访问 elasticsearch;
  • 将用户的软硬限制进行调整,打开"/etc/security/limits.conf"添加配置;
  • 调整虚拟内存大小,将虚拟内存调整至 262144;
  • 切换到"es"用户,启动 elasticsearch。

二、Logstash

Logstash 是一款开源的数据收集引擎,其中内置了约 200 个插件,可接受各种类型的数据(日志、网络请求、关系型数据库、传感器或物联网等)。Logstash 由输入、过滤器和输出三大类插件组成:

Logstash 配置文件结构如下:

PYTHON
input {   # 输入组件配置
}
filter {  # 过滤组件配置
}
output {  # 输出组件配置
}

使用 Logstash 进行数据收集时需要手动创建扩展名为".conf"的配置文件,并输入三个组件的配置即可,然后使用 Logstash 命令启动数据收集:

PYTHON
logstash -f ./logstash.conf

Logstash 中提供了数十种过滤插件,并且在 Logstash 中过滤插件是功能最强大、配置最为复杂的插件。过滤插件能够根据要求对数据在采集过程中进行初步的筛选或格式化操作。

grok 过滤器能够将非结构化日志数据解析为结构化数据。 %{SYNTAX:SEMANTIC}

geoip 能够根据免费的 IP 地址提供对应的地域信息,其中包括国家、省市和经纬度等,用于绘制可视化地图,主要应用在根据地域统计访问流量的场景。

Logstash 提供了数十种输出配置插件,能够适应不同的应用场景和业务需求,常用的就是标准输出 stdout 和 Elasticsearch 两类。其中 stdout 在前面示例已经应用过,这里使用 Logstash 采集数据输出到 Elasticsearch。

参数描述
hosts指定 Elasticsearch 的主机地址和端口
index事件索引,默认值为 logstash-%{+YYYY.MM.dd}

三、Kibana

Kibana 是一个开源的分析与可视化平台,配合 Elasticsearch 能够实现数据的检索、查看、交互存放以及数据的可视化,可通过丰富的图表功能直观地展示数据信息,达到数据分析的目的。Elasticsearch、Logstash 和 Kibana 个技术简称为 ELK。

四、任务实施(6 步)

  • 在"/usr/local/inspur/"目录中创建名为 data 的文件夹;
  • 在"/usr/local/inspur/code/flume-code"目录下编写 Flume 配置文件,采集 /usr/local/inspur/data 目录下名为 access_2021_05_01.log 的日志文件;
  • 使用"es"用户启动 Elasticsearch 服务;
  • 使用 Logstash 消费 Kafka 的数据并对其进行正则匹配,将结果输出到 Elasticsearch,设置 index 为"inspur-logdata-2022";
  • 将日志文件上传到"/usr/local/inspur/data"目录下,查看 logstash 窗口输出内容;
  • 使用浏览器访问 Kibana 页面。
06

知识拓展与实例案例

课堂讲解用:3 个可运行实例 + 知识拓展卡片。

知识拓展

实例 1:Pandas 新闻数据完整清洗实战

目标:对一份新闻采集结果执行"读取 → 检查 → 去重 → 填充 → 保存"的完整清洗流程。

PYTHON
# pandas_clean.py
import pandas as pd

# 1. 读取采集到的新闻数据
df = pd.read_csv("news_raw.csv")

# 2. 检查基本信息与缺失情况
print("维度:", df.shape)
print("列名:", list(df.columns))
print("缺失统计:\n", df.isna().sum())

# 3. 去重:按"标题"去重,保留第一条
df = df.drop_duplicates(subset=["标题"])

# 4. 填充:标题为空用"未知",阅读量为空用 0
df["标题"] = df["标题"].fillna("未知")
df["阅读量"] = df["阅读量"].fillna(0)

# 5. 类型转换:阅读量转为整数
df["阅读量"] = df["阅读量"].astype(int)

# 6. 保存清洗结果
df.to_csv("news_clean.csv", index=False, encoding="utf-8-sig")
print("清洗后剩余:", len(df), "条")
PYTHON
维度: (120, 5)
列名: ['标题', '发布时间', '来源', '链接', '阅读量']
缺失统计:
 标题      2
发布时间    0
来源      0
链接      0
阅读量     1
清洗后剩余: 112 条
代码白话解释
import pandas as pd导入 pandas 并起别名 pd。pandas 是 Python 处理表格数据的王牌库,全课程都用 pd 这个缩写。
df = pd.read_csv("news_raw.csv")读取 CSV 文件,转成"数据表"对象 DataFrame 存入 df。一行代码就把文件变成表格,非常方便。
df.shape / df.isna().sum()shape 返回表格的(行数,列数);isna() 判断每个单元格是否为空(空=True),sum() 把每列的空值数量加起来——快速掌握"哪里缺数据"。
df = df.drop_duplicates(subset=["标题"])按"标题"列去掉重复行、保留第一条。注意要重新赋值给 df,因为该方法默认返回新表、不原地修改。
df["标题"] = df["标题"].fillna("未知")取"标题"这一列,把空值(NaN)填成"未知"两个字,避免后续处理报错。
df["阅读量"] = df["阅读量"].astype(int)astype(int) 把该列数据类型转成整数。转成整数后才能做求和、平均等数学运算。
df.to_csv("news_clean.csv", index=False, encoding="utf-8-sig")把处理好的表保存成新文件。index=False 表示不保存行号;utf-8-sig 让 Excel 打开不乱码。

实例 2:Pandas 分组统计新闻来源

目标:对清洗后的新闻数据按"来源"分组,统计各来源的新闻数量与平均阅读量。

PYTHON
# pandas_groupby.py
import pandas as pd

df = pd.read_csv("news_clean.csv")

# 按"来源"分组,聚合新闻条数与平均阅读量
result = df.groupby("来源").agg(
    条数=("标题", "count"),
    平均阅读量=("阅读量", "mean")
).reset_index()

# 按条数降序排列
result = result.sort_values("条数", ascending=False)
print(result)

# 输出各来源占比
total = result["条数"].sum()
for _, row in result.iterrows():
    print(f"{row['来源']}:{row['条数']} 条,占比 {row['条数']/total:.1%}")
PYTHON
     来源  条数   平均阅读量
0  官方发布    45  1325.6
1  校园新闻    38   876.4
2  行业资讯    29  1102.3
官方发布:45 条,占比 40.2%
校园新闻:38 条,占比 33.9%
行业资讯:29 条,占比 25.9%
代码白话解释
df = pd.read_csv("news_clean.csv")读取上一步清洗好的数据文件,得到 DataFrame 表 df。
df.groupby("来源")按"来源"列分组:把同一来源的新闻归到一组。想象把一叠卡片按颜色分成几摞。
.agg(条数=("标题", "count"), 平均阅读量=("阅读量", "mean"))对每组做统计:count 数一数每组有多少条(统计标题列的数量),mean 算一算每组平均阅读量。结果列名就叫"条数"和"平均阅读量"。
.reset_index()把"来源"从索引变回普通列,表格更直观,方便后续保存为 CSV。
result.sort_values("条数", ascending=False)按"条数"从大到小排序,最多的来源排在最上面。
for _, row in result.iterrows():iterrows() 逐行取出结果表;_ 表示不需要的行号,row 是当前行数据。
print(f"{row['来源']}:{row['条数']} 条,占比 {row['条数']/total:.1%}")f-string 格式化输出:打印来源、条数和占比。{...:.1%} 表示把小数显示成百分比、保留 1 位小数。

实例 3:Logstash grok 解析一行真实日志

目标:用 grok 过滤器把一行非结构化日志解析为结构化字段,输出到 Elasticsearch。

PYTHON
# logstash.conf —— 解析 Nginx 访问日志
input {
  kafka {
    bootstrap_servers => "localhost:9092"
    topics => ["nginx-log"]
    codec => "json"
  }
}

filter {
  grok {
    # 匹配:客户端IP 时间 "请求" 状态码 字节 来源
    match => { "message" => "%{IP:client_ip} \[%{HTTPDATE:time}\] \"%{WORD:method} %{URIPATHPARAM:request}\" %{INT:status} %{INT:bytes} \"%{DATA:referer}\"" }
  }
  date {
    match => ["time", "dd/MMM/yyyy:HH:mm:ss Z"]
    target => "@timestamp"
  }
  geoip {
    source => "client_ip"
  }
}

output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "inspur-logdata-2022"
  }
  stdout { codec => rubydebug }
}

# 启动
[root@master logstash]# bin/logstash -f logstash.conf
PYTHON
# 输入日志样例
192.168.1.10 [10/Feb/2022:10:15:30 +0800] "GET /index.html HTTP/1.1" 200 5120 "-"

# 解析后的结构化字段
client_ip : 192.168.1.10
method    : GET
request   : /index.html
status    : 200
bytes     : 5120
@timestamp: 2022-02-10T02:15:30.000Z
配置项白话解释
input { kafka { ... } }数据入口:从 Kafka 的 nginx-log 主题读取日志消息。相当于"水龙头"打开,让日志流进来。
filter { grok { match => { "message" => "..." } } }grok 过滤器:按模式匹配日志文本。%{IP:client_ip} 表示"这里应是一个 IP,命名为 client_ip"。一行日志被拆成多个字段。
%{HTTPDATE:time}匹配形如 [10/Feb/2022:10:15:30 +0800] 的时间字符串,命名为 time。
%{INT:status} / %{INT:bytes}匹配整数(状态码、字节数)。INT 是预定义的"整数"模式。
date { match => ["time", "dd/MMM/yyyy:HH:mm:ss Z"] }date 过滤器:把 time 字符串按给定格式解析成标准时间,存入 @timestamp——Elasticsearch 里按时间检索就靠它。
geoip { source => "client_ip" }geoip 过滤器:根据 IP 自动补充地理位置字段(国家、城市、经纬度等)。
output { elasticsearch { index => "inspur-logdata-2022" } }数据出口:把处理好的结构化日志写入 Elasticsearch,索引名(index)为 inspur-logdata-2022,可理解成"数据库里的表名"。
bin/logstash -f logstash.conf用 -f 指定配置文件启动 Logstash,加载 input/filter/output 三段配置。