POLOXUE's BLOG

POLOXUE's BLOG

10 Dec 2024

数据清洗与预处理:做好分析的第一步

在做数据分析或时,有没有碰到过这样的情况:数据明明下载下来了,却发现了一些问题。比如有的数据缺失,有的地方重复了,还有的怎么看都觉得异常。这个时候,你可能会想:“这数据还能用吗?”

今天,就来聊聊数据清洗和预处理,用一个常见的股票行情数据作为例子,走一遍实际的操作。你会发现,这并不是一件多难的事。


数据清洗是什么?为什么重要?

简单来说,数据清洗和预处理就是给你的原始数据“洗澡”,把里面的脏东西都清理干净。我们要检查缺失值、重复值,甚至一些很怪的异常值。为什么要做这件事呢?很简单,因为“垃圾数据”会让分析结果一团糟,俗话说:“垃圾进,垃圾出(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()

数据清洗的几点建议

从最基本的检查开始

借助可视化工具

多数据源验证

记得定期更新数据


总结

清洗数据就像是搭建房子的地基,虽然不是最吸引人的部分,但却是最重要的环节之一。通过处理缺失值、去掉重复数据、检测异常值等步骤,我们可以确保数据的准确性和可靠性。

希望通过今天的案例,你能对数据清洗有更清晰的认识。下次拿到数据的时候,不妨试试这些方法,帮你打好分析的基础。

本文来源于 POLOXUE's BLOG,地址: 数据清洗与预处理:做好分析的第一步
欢迎关注我的公众号: