我的,样本量是三万多,如何在Jupyter note book中检验包含坐标数据(X,Y,Z)的excel数据中Z列的正态性
时间: 2025-07-12 20:36:54 浏览: 10
<think>好的,用户现在有一个样本量三万多的Excel数据,里面有X、Y、Z三列坐标数据,他想在Jupyter Notebook中检验Z列的正态性。首先,我需要回顾一下正态性检验的常用方法,然后考虑如何在Python中实现这些方法,特别是针对大数据量的情况。
用户之前的问题是关于删除异常值的,现在转向正态性检验,可能是在数据清洗之后需要进一步分析数据分布。考虑到样本量很大,三万多条数据,这时候需要注意检验方法的选择,因为像Shapiro-Wilk这样的检验在大样本时可能会过于敏感,即使很小的偏离也会拒绝正态性假设。
首先,我应该列出几种常用的正态性检验方法,比如Shapiro-Wilk检验、Kolmogorov-Smirnov检验、D'Agostino's K-squared检验,以及图形方法如QQ图和直方图。对于大样本,可能需要结合图形和统计检验,同时考虑计算效率。
然后,具体步骤可能包括:
1. 数据加载:使用pandas读取Excel文件。
2. 数据预览:查看前几行,确保数据正确加载。
3. 缺失值检查:确保Z列没有缺失值,否则需要处理。
4. 可视化分析:绘制直方图、密度图、QQ图,直观判断正态性。
5. 统计检验:应用几种统计检验方法,并解释结果。
6. 结果总结:结合图形和检验结果给出结论。
需要注意的是,大样本数据在可视化时可能会因为数据点过多导致图表不清晰,可能需要调整分箱数或使用核密度估计。另外,执行统计检验时要考虑p值的意义,大样本下p值可能很小,即使偏差很小也会显著,因此不能单纯依赖p值。
在代码实现方面,需要导入必要的库,如pandas、numpy、scipy.stats、matplotlib、statsmodels等。对于QQ图,使用statsmodels的qqplot函数。统计检验部分,使用scipy的shapiro、normaltest、kstest等函数。
此外,用户可能需要了解每种检验的适用情况和限制,特别是样本量对检验结果的影响。例如,Shapiro-Wilk适用于小样本,而Kolmogorov-Smirnov可以用于大样本,但参数设置需要注意。D'Agostino's K-squared检验基于偏度和峰度,适用于大样本。
最后,给出代码示例时,要确保代码在Jupyter Notebook中能够分段执行,并附上必要的注释,方便用户理解和调整参数。同时,提醒用户如果数据量太大导致计算缓慢,可以考虑抽样或使用更高效的方法。</think>---
### **针对3万+样本量的Z列正态性检验分步指南**
---
#### **一、环境准备**
```python
# 安装必要库(若未安装)
!pip install pandas numpy scipy matplotlib statsmodels
# 导入库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
import statsmodels.api as sm
```
---
#### **二、数据加载与预处理**
```python
# 读取Excel数据(建议指定工作表)
df = pd.read_excel("坐标数据.xlsx", sheet_name="Sheet1")
# 检查数据规模
print(f"数据维度:{df.shape}") # 预期输出 (30000+, 3)
# 检查Z列基本情况
print(df['Z'].describe())
# 处理缺失值(如有)
if df['Z'].isnull().sum() > 0:
print(f"发现{df['Z'].isnull().sum()}个缺失值,已自动删除")
df = df.dropna(subset=['Z'])
```
---
#### **三、可视化检验(大数据优化版)**
##### **1. 直方图+核密度曲线**
```python
plt.figure(figsize=(12,5))
# 使用对数刻度处理大样本
plt.hist(df['Z'], bins=100, density=True, alpha=0.6, color='g',
edgecolor='black', log=True) # log=True优化显示
# 添加理论正态曲线
mu, std = df['Z'].mean(), df['Z'].std()
xmin, xmax = plt.xlim()
x = np.linspace(xmin, xmax, 1000)
p = ((1 / (np.sqrt(2 * np.pi) * std)) *
np.exp(-0.5 * ((x - mu)/std)**2))
plt.plot(x, p, 'r', linewidth=2)
plt.title("Z列分布与理论正态对比(对数刻度)")
plt.show()
```
##### **2. 分位数-分位数图(QQ Plot)**
```python
plt.figure(figsize=(8,8))
sm.qqplot(df['Z'], line='s', markersize=3) # line='s'表示理论斜线
plt.title("QQ Plot - 正态性检验")
plt.show()
```
##### **3. 箱线图(异常值检测)**
```python
plt.figure(figsize=(6,4))
df['Z'].plot.box(vert=False)
plt.title("Z列箱线图")
plt.show()
```
---
#### **四、统计检验方法**
##### **1. Shapiro-Wilk检验**
```python
# 注意:当n>5000时自动采用近似算法
stat, p = stats.shapiro(df['Z'])
print(f'Shapiro-Wilk检验:统计量={stat:.4f}, p值={p:.3e}')
'''
* 解读:
- p > 0.05 → 不能拒绝正态性假设
- 大样本下此检验过于敏感,需谨慎参考
'''
```
##### **2. D'Agostino K²检验**
```python
k2, p = stats.normaltest(df['Z'])
print(f"D'Agostino检验:统计量={k2:.1f}, p值={p:.3e}")
'''
* 原理:基于偏度+峰度的组合检验
* 优势:适用于大样本(n>50)
'''
```
##### **3. Kolmogorov-Smirnov检验**
```python
# 生成理论正态分布样本
normal_sample = np.random.normal(mu, std, len(df))
stat, p = stats.kstest(df['Z'], normal_sample)
print(f'K-S检验:统计量={stat:.4f}, p值={p:.3e}')
'''
* 注意:需要标准化数据后再检验更准确
'''
```
---
#### **五、大样本分析技巧**
1. **抽样检验**(解决计算资源问题)
```python
# 随机抽取5000个样本
sample = df['Z'].sample(n=5000, random_state=42)
stat, p = stats.shapiro(sample)
```
2. **分段检验**(检测分布一致性)
```python
# 将数据分为10个区间段
segments = np.array_split(df['Z'], 10)
for i, seg in enumerate(segments):
_, p = stats.normaltest(seg)
print(f"第{i+1}段p值:{p:.3f}")
```
3. **效应量分析**(超越p值局限)
```python
# 计算偏度/峰度的Z分数
skew_z = stats.skew(df['Z'])/stats.skewtest(df['Z'])[1]
kurt_z = stats.kurtosis(df['Z'])/stats.kurtosistest(df['Z'])[1]
print(f"偏度Z分数:{skew_z:.2f},峰度Z分数:{kurt_z:.2f}")
```
---
#### **六、结果解读框架**
| 检验方法 | 适用场景 | 3万样本关注点 |
|----------|----------|--------------|
| Shapiro-Wilk | 小样本更准 | 主要参考效应量而非p值 |
| D'Agostino | 大样本首选 | 关注偏度/峰度组合异常 |
| QQ图 | 直观形态分析 | 重点观察两端尾部偏差 |
| 直方图 | 分布形态展示 | 使用对数刻度优化显示 |
**决策建议**:
1. 如果所有检验p值均<0.05 → 但效应量小 → 可视为近似正态
2. 如果QQ图仅尾部轻微偏离 → 不影响多数统计分析
3. 如果显著右偏/左偏 → 考虑数据转换(如log变换)
---
#### **七、完整代码整合**
```python
# 完整检验流程函数
def normality_check(data_series, alpha=0.05):
"""大数据正态性检验工具函数"""
# 基础信息
n = len(data_series)
print(f"\n=== 正在分析 {n} 条数据 ===")
# 可视化模块
fig, ax = plt.subplots(1,3, figsize=(18,5))
# 直方图
ax[0].hist(data_series, bins=100, density=True, alpha=0.6,
edgecolor='black', log=True)
mu, std = data_series.mean(), data_series.std()
x = np.linspace(data_series.min(), data_series.max(), 1000)
ax[0].plot(x, stats.norm.pdf(x, mu, std), 'r')
ax[0].set_title('直方图对比')
# QQ图
sm.qqplot(data_series, line='s', ax=ax[1], markersize=3)
ax[1].set_title('QQ Plot')
# 箱线图
data_series.plot.box(ax=ax[2], vert=False)
ax[2].set_title('箱线图')
plt.tight_layout()
plt.show()
# 统计检验
print("\n【统计检验结果】")
# Shapiro-Wilk
if n <= 5000:
sw_stat, sw_p = stats.shapiro(data_series)
print(f"Shapiro-Wilk: p={sw_p:.3e} {'(未拒绝正态)' if sw_p>alpha else '**拒绝正态**'}")
else:
print("Shapiro-Wilk: 样本量>5000不推荐使用")
# D'Agostino
k2, dag_p = stats.normaltest(data_series)
print(f"D'Agostino: p={dag_p:.3e} {'(未拒绝正态)' if dag_p>alpha else '**拒绝正态**'}")
# 效应量分析
skewness = stats.skew(data_series)
kurt = stats.kurtosis(data_series)
print(f"\n【效应量】偏度={skewness:.2f} (绝对值>1为显著),峰度={kurt:.2f} (>3为尖峰)")
# 执行检验
normality_check(df['Z'])
```
---
#### **八、典型结果案例**
**近似正态数据**:
```
=== 正在分析 32567 条数据 ===
【统计检验结果】
Shapiro-Wilk: 样本量>5000不推荐使用
D'Agostino: p=1.235e-05 **拒绝正态**
【效应量】偏度=0.12 (绝对值>1为显著),峰度=0.35 (>3为尖峰)
```
* 解读:虽统计检验拒绝正态,但偏度/峰度接近理想值(0和0),可视为近似正态
**明显非正态数据**:
```
【效应量】偏度=2.15 (绝对值>1为显著),峰度=5.78 (>3为尖峰)
```
* 建议:进行log变换或使用非参数方法
---
通过这种多维度验证方法,即使在大样本情况下也能准确评估正态性特征,为后续选择统计分析方法提供可靠依据。
阅读全文
相关推荐



















