
在做数据分析或时,有没有碰到过这样的情况:数据明明下载下来了,却发现了一些问题。比如有的数据缺失,有的地方重复了,还有的怎么看都觉得异常。这个时候,你可能会想:“这数据还能用吗?”
今天,就来聊聊数据清洗和预处理,用一个常见的股票行情数据作为例子,走一遍实际的操作。你会发现,这并不是一件多难的事。
数据清洗是什么?为什么重要?
简单来说,数据清洗和预处理就是给你的原始数据“洗澡”,把里面的脏东西都清理干净。我们要检查缺失值、重复值,甚至一些很怪的异常值。为什么要做这件事呢?很简单,因为“垃圾数据”会让分析结果一团糟,俗话说:“垃圾进,垃圾出(Garbage in, garbage out)。”
如果你不想做了半天无用功,那就得花时间好好清理数据。
用股票行情数据举个例子
假设我们从两个地方下载了同一只股票的每日收盘价数据,分别叫数据集 A 和数据集 B。看起来差不多,但仔细一看就发现问题多了去了:有缺失值、有重复记录,还有价格离谱的异常点。接下来,我们一步步清理。
处理缺失值
我们发现数据集 A 中有些日期的收盘价是空的。这种情况怎么办呢?有两种简单的办法:
- 删掉空行:如果缺失的数据不多,可以直接删掉。
- 填补空缺:比如用前一天的数据、平均值或者插值。
示例操作:
1
2
3
4
5
6
7
8
9
| import pandas as pd
import numpy as np
# 模拟数据
data = {
'Date': ['2024-12-01', '2024-12-02', '2024-12-03', '2024-12-04'],
'Close Price': [100, 101, np.nan, 103],
}
df = pd.DataFrame(data)
|
我们可以删除缺失值,如下:
1
2
| df_cleaned = df.dropna()
print(df_cleaned)
|
输出:
1
2
3
4
| Date Close Price
0 2024-12-01 100.0
1 2024-12-02 101.0
3 2024-12-04 103.0
|
或者用插值法填补缺失值,如下:
1
2
| df_filled = df.interpolate()
print(df_filled)
|
输出:
1
2
3
4
5
| Date Close Price
0 2024-12-01 100.0
1 2024-12-02 101.0
2 2024-12-03 102.0
3 2024-12-04 103.0
|
小提示:如果缺失值太多,可能就要重新找数据源了。
去掉重复数据
如果我们的数据集中某些日期重复了多次,如同一天的收盘价被记录了两次。重复的数据会导致分析时重复计算,得出的结果可能偏差很大。
通过如下代码可直接删除重复值:
1
2
3
4
5
6
7
| data = {
'Date': ['2024-12-01', '2024-12-01', '2024-12-02', '2024-12-03', '2024-12-04'],
'Close Price': [100, 100, 101, np.nan, 103],
}
df = pd.DataFrame(data)
df_cleaned = df.drop_duplicates()
print(df_cleaned)
|
输出:
1
2
3
4
| 0 2024-12-01 100.0
2 2024-12-02 101.0
3 2024-12-03 NaN
4 2024-12-04 103.0
|
检测异常值
如果某一天的价格突然跳到 500,而前一天才 100,这怎么看都不正常。我们可以通过检测价格的变化幅度来发现这些异常点。比如,如果价格波动超过 50%,就需要进一步检查。
示例操作:
1
2
3
4
5
6
7
8
9
10
| data = {
'Date': ['2024-12-01', '2024-12-02', '2024-12-03', '2024-12-04'],
'Close Price': [100, 101, 500, 103], # 500 是异常值
}
df = pd.DataFrame(data)
# 检测价格波动是否异常
df['Pct Change'] = df['Close Price'].pct_change()
df['Anomaly'] = df['Pct Change'].abs() > 0.5
print(df[df['Anomaly']]) # 打印异常值
|
输出:
1
2
3
| Date Close Price Pct Change Anomaly
2 2024-12-03 500 3.950495 True
3 2024-12-04 103 -0.794000 True
|
解决方法:如果确定是录入错误,可以用前一天的价格或者移动平均值替代。
检查日期是否正确
股票市场一般只在工作日交易,周末和节假日是不会有数据的。所以我们需要检查数据中是否有周末的记录,或者日期格式是否一致。
示例操作:
1
2
3
4
5
6
| # 转换日期格式并检查周末数据
df['Date'] = pd.to_datetime(df['Date'])
# 检查是否有周末数据
df['Weekday'] = df['Date'].dt.weekday
print(df[df['Weekday'] >= 5]) # 打印周末数据
|
可视化检查
如果你不确定哪里出了问题,可以试着把数据画成图表,这样异常点一眼就能看出来。比如我们可以绘制收盘价随时间的变化趋势。
示例操作:
1
2
3
4
5
6
7
8
| import matplotlib.pyplot as plt
# 绘制收盘价趋势图
plt.plot(df['Date'], df['Close Price'], marker='o')
plt.title('Stock Closing Prices Over Time')
plt.xlabel('Date')
plt.ylabel('Close Price')
plt.show()
|
数据清洗的几点建议
从最基本的检查开始
- 查找缺失值、重复值和格式问题。
- 确保日期、单位等字段一致。
借助可视化工具
多数据源验证
- 如果一个数据源问题太多,可以参考其他数据源交叉验证。
记得定期更新数据
总结
清洗数据就像是搭建房子的地基,虽然不是最吸引人的部分,但却是最重要的环节之一。通过处理缺失值、去掉重复数据、检测异常值等步骤,我们可以确保数据的准确性和可靠性。
希望通过今天的案例,你能对数据清洗有更清晰的认识。下次拿到数据的时候,不妨试试这些方法,帮你打好分析的基础。
欢迎关注我的公众号:
