3.数据预览与预处理
本文最后更新于 2025年7月27日 晚上
初始化与加载数据
在开始之前,我们还是需要先导入 pandas
库,并加载本期练习所需的数据集 TOP250.xlsx
。
1 |
|
数据查看
拿到一个数据集后,首要任务就是像侦探一样,从不同角度审视它,了解其规模、结构和内容。
1. 查看数据维度
- 题目: 先看看数据多少行,多少列,对接下来的处理量心里有个数。
- 答案:
1
df.shape
- 解释:
df.shape
是 DataFrame 的一个属性(注意后面没有括号),它会返回一个**元组 (tuple)**。- 元组的第一个元素代表行数,第二个元素代表列数。
- 这是了解数据规模最快、最直接的方法。
2. 随机查看5条数据
- 题目: 随机查看5条数据。
- 答案:
1
df.sample(5)
- 解释:
df.sample(n)
是一个非常有用的方法,它可以从 DataFrame 中随机抽取 n 条数据。- 为什么要用随机查看?相比于只看开头或结尾的数据,随机抽样能更客观地反映数据集中间部分的情况,避免因数据排序带来的片面印象。
3. 查看数据前后5行
- 题目: 查看数据前后5行。
- 答案:
1
2
3
4
5# 查看前5行
df.head()
# 查看后5行
df.tail() - 解释:
df.head(n)
查看 DataFrame 的前 n 行(默认为 5)。df.tail(n)
查看 DataFrame 的后 n 行(默认为 5)。- 这两个方法可以帮助我们快速检查数据是否加载正确,表头是什么,数据的大致格式,以及是否有明显的排序规律。
4. 查看数据基本信息
- 题目: 看看数据类型,有无缺失值什么的。
- 答案:
1
df.info()
- 解释:
df.info()
是数据概览的“神器”,它会打印出 DataFrame 的摘要信息,包括:- 索引类型和范围:
RangeIndex: 250 entries, 0 to 249
- 总列数:
Data columns (total 10 columns):
- 每列的信息:
- 列名: 如
片名
- 非缺失值数量:
248 non-null
,这直接告诉我们该列有多少缺失值(总行数 - 非缺失值数量)。 - 数据类型 (Dtype): 如
object
(通常是字符串)、float64
(浮点数)、int64
(整数)。
- 列名: 如
- 内存占用:
memory usage: ...
- 索引类型和范围:
5. 查看数据统计信息|数值
- 题目: 查看 数值型 列的统计信息,计数、均值什么的。
- 答案:
1
df.describe()
- 解释:
df.describe()
会对所有数值类型(如int64
,float64
)的列进行描述性统计,输出包括:count
: 非缺失值的数量mean
: 平均值std
: 标准差min
: 最小值25%
,50%
,75%
: 分别代表第一、第二(中位数)、第三四分位数max
: 最大值
- 这能帮我们快速了解数值数据的分布情况,比如评分范围、评价人数的量级等。
6. 查看数据统计信息|离散
- 题目: 查看 离散型 列的统计信息,计数、频率什么。
- 答案:
1
df.describe(include=['object'])
- 解释:
describe()
方法可以通过include
参数来指定要统计的数据类型。include=['object']
表示我们只想看对象类型(通常是字符串)列的统计信息,输出包括:count
: 非缺失值的数量unique
: 有多少个不重复的类别top
: 出现次数最多的类别是什么freq
:top
类别出现的次数
7. 查看数据统计信息|整体
- 题目: 查看 全部 列的统计信息。
- 答案:
1
df.describe(include='all')
- 解释:
include='all'
会将数值型和离散型列的统计信息合并在一起展示。- 对于数值列,离散型统计(如
unique
,top
)会显示为NaN
;反之亦然。
缺失值处理
数据很少是完美的,缺失值是家常便饭。处理缺失值是数据预处理的核心步骤。
8. 计算缺失值|总计
- 题目: 看看一共存在多少个缺失值。
- 答案:
1
df.isnull().sum().sum()
- 解释:
df.isnull()
: 这个操作会返回一个和df
同样大小的 DataFrame,但元素是布尔值 (True
/False
)。True
表示该位置是缺失值 (NaN
),False
则表示不是。df.isnull().sum()
: 对布尔值 DataFrame 按列求和。True
被当作 1,False
被当作 0。所以结果是一个 Series,显示每列的缺失值数量。df.isnull().sum().sum()
: 对上一步得到的 Series 再次求和,得到整个 DataFrame 的总缺失值数量。
9. 计算缺失值|分列
- 题目: 再看看具体每列有多少缺失值。
- 答案:
1
df.isnull().sum()
- 解释:
- 这就是上一步的中间结果,它清晰地列出了每一列包含的缺失值个数,让我们能定位到问题所在的列。
10. 查看缺失值
- 题目: 看看全部缺失值所在的行。
- 答案:
1
df[df.isnull().any(axis=1)]
- 解释:
df.isnull()
: 得到布尔值 DataFrame。.any(axis=1)
:any()
方法用于检查是否有任何True
存在。axis=1
表示按行检查。所以,如果某一行有任意一个单元格是True
(即有缺失值),any()
就会返回True
。df[...]
: 最后,我们用这个布尔值的 Series 来过滤原始的 DataFrame,就只筛选出了那些至少包含一个缺失值的行。
11. 高亮缺失值
- 题目: 将缺失值进行高亮进一步查看。
- 答案:
1
df.style.highlight_null(color='red')
- 解释:
df.style
会返回一个 Styler 对象,允许我们对 DataFrame 的显示样式进行美化(这在 Jupyter Notebook 中特别有用)。.highlight_null()
是一个样式函数,它会自动找到所有的缺失值,并用指定的颜色(这里是红色)进行高亮。这比纯文本查看要直观得多。
12. 删除缺失值
- 题目: 将缺失值出现的行全部删掉。
- 答案:
1
df_no_na = df.dropna()
- 解释:
dropna()
是处理缺失值最简单粗暴的方法。- 默认情况下(
how='any'
),它会删除任何包含至少一个缺失值的行。 - 注意: 这是一种有损操作,可能会丢失大量信息,尤其是在数据稀疏的情况下,所以使用前要慎重。
13. 缺失值补全|整体填充
- 题目: 将全部缺失值替换为
*
。 - 答案:
1
df_filled_star = df.fillna('*')
- 解释:
fillna()
是用于填充缺失值的核心方法。- 当给它传入一个具体的值(如字符串
*
、数字 0 等)时,它会将 DataFrame 中所有的NaN
都替换成这个值。
14. 缺失值补全|向上填充
- 题目: 将评分列的缺失值,替换为上一个电影的评分。
- 答案:
1
df['评分'] = df['评分'].ffill()
- 解释:
ffill()
(forward fill) 会用前一个非缺失值来填充当前的缺失值。- 因为数据是按评分排序的,这种方法在一定程度上是合理的。与之对应的是
bfill()
(backward fill),用后一个值来填充。
15. 缺失值补全|整体均值填充
- 题目: 将评价人数列的缺失值,用整列的均值进行填充。
- 答案:
1
2mean_value = df['评价人数'].mean()
df['评价人数'] = df['评价人数'].fillna(mean_value) - 解释:
- 这是处理数值型特征缺失值最常用的方法之一。
df['评价人数'].mean()
计算出该列的平均值。- 然后将这个计算出的平均值作为
fillna()
的参数,对该列的缺失值进行填充。
16. 缺失值补全|上下均值填充
- 题目: 将评价人数列的缺失值,用上下数字的均值进行填充。
- 答案:
1
df['评价人数'] = df['评价人数'].interpolate()
- 解释:
interpolate()
是一个更高级的填充方法,专门用于数值数据。- 默认情况下,它使用线性插值。简单来说,如果一个值缺失了,它会取其“邻居”(上一个和下一个有效值)的平均值来填充。这通常比用整列的均值填充更精确。
17. 缺失值补全|匹配填充
题目: 填充 “语言” 列的缺失值,要求根据 “国家/地区” 列的值进行填充。
答案: (这里提供两种思路)
方法一:使用
groupby
和transform
(更强大灵活)1
df['语言'] = df.groupby('国家/地区')['语言'].transform(lambda x: x.mode()[0] if not x.mode().empty else None)
方法二:创建映射字典后填充 (更易于理解)
1
2
3
4
5# 1. 创建一个“国家/地区”到“最常见语言”的映射
lang_map = df.groupby('国家/地区')['语言'].apply(lambda x: x.mode()[0] if not x.mode().empty else None)
# 2. 填充缺失值
df['语言'] = df['语言'].fillna(df['国家/地区'].map(lang_map))解释:
- 这是一个非常经典的分组填充问题,核心思想是:用同一组内的数据特征来填充缺失值。
groupby('国家/地区')
: 首先按“国家/地区”列进行分组。['语言']
: 在每个分组内,我们关注“语言”这一列。x.mode()[0]
: 对于每个国家分组内的所有语言 (x
),我们计算**众数 (mode
)**,也就是出现次数最多的语言,并取第一个结果 ([0]
)。transform
: 它的强大之处在于,它会将计算结果(每个分组的众数)“广播”回原始的 DataFrame 形状,可以直接用于赋值。- 第二种方法思路更清晰,先创建一个映射关系,再用
.map()
方法根据“国家/地区”列的值去查找对应的语言来填充,两者效果一致。
重复值处理
重复的数据行会影响统计分析的准确性,需要识别并处理。
18. 查找重复值
- 题目: 将全部重复值所在的行筛选出来。
- 答案:
1
df[df.duplicated()]
- 解释:
df.duplicated()
会返回一个布尔 Series。对于某一行,如果它与前面出现过的某一行完全相同,则标记为True
。- 用这个布尔 Series 过滤 DataFrame,即可找出所有(除第一次出现外的)重复行。
19. 查找重复值|指定
- 题目: 查找
片名
列全部重复的行。 - 答案:
1
df[df.duplicated(subset=['片名'], keep=False)]
- 解释:
subset=['片名']
:duplicated
方法的subset
参数让我们只根据指定的列(这里是片名
)来判断是否重复,而不是比较整行。keep=False
: 这是一个关键参数。默认的keep='first'
只会标记第二次、第三次出现的重复项为True
。而keep=False
会将所有出现重复的项(包括第一次出现的)都标记为True
。这能帮助我们看到所有相关的重复记录。
20. 删除重复值
- 题目: 删除全部的重复值。
- 答案:
1
df_deduplicated = df.drop_duplicates()
- 解释:
drop_duplicates()
是用于删除重复行的方法。- 默认情况下(
keep='first'
),它会删除所有重复的行,只保留第一次出现的那一行。
21. 删除重复值|指定
- 题目: 删除全部的重复值,但保留最后一次出现的值。
- 答案:
1
df_deduplicated_last = df.drop_duplicates(keep='last')
- 解释:
keep='last'
参数会改变删除逻辑,删除所有重复的行,但保留最后一次出现的那一行。
3.数据预览与预处理
https://blog.wyyy.dpdns.org/2025/3-数据预览与预处理/