11.6 数据分析中的常用方法及运用场景(入门)¶

本节是一个工具箱导览:从“该用什么方法”到“如何快速落地”。配套 Python 小例子都能直接运行,适合人文社科初学者。

学习目标¶

  • 认识常见数据分析方法与典型运用场景。
  • 熟悉 Python 常用库在数据分析中的定位与分工。
  • 会用最小代码完成:描述统计、频数/交叉表、文本词频、时间序列折线图。
  • 能根据研究问题选择合适方法,并知道常见坑点与规避策略。

11.6.1 常用方法及运用场景(速查表)¶

方法名称 描述 运用场景
描述性统计 总结均值、中位数、标准差等 学生成绩分布、问卷汇总
数据清洗 处理缺失、重复、异常 文献/问卷/社交数据清洗
数据可视化 图表展示分布与关系 趋势分析、词频可视化
假设检验 检验样本是否支持总体假设 成绩差异显著性
相关性分析 计算变量相关程度 投入与结果关系
回归分析 构建预测模型 房价/成绩预测
文本分析 分词、词频、情感 诗歌情感、话题挖掘
聚类分析 无监督分组 消费者群体划分
时间序列分析 研究随时间的变化 历史趋势、价格变化
主成分分析(PCA) 高维降维 特征压缩与解释
频数分析 分类频率与占比 性别/职业分布
交叉表分析 分类变量关系 性别×职业对应关系

11.6.2 常用 Python 库(做什么用?)¶

  • Pandas:表格数据读取、整理、聚合分析(CSV/Excel 等)。
  • NumPy:数组运算与数学函数(Pandas 的底层伙伴)。
  • Matplotlib:绘图(本节只用它,保证环境通用)。
  • SciPy / Statsmodels:统计检验与回归(可选)。
  • Scikit-learn:机器学习建模(聚类、PCA、回归等,入门了解即可)。
  • NLTK / TextBlob:文本处理(本节用 Python 内置方法演示词频)。

语法要点(本节会用到)¶

  • pd.Series(...).mean()/median()/std():描述统计。
  • value_counts(normalize=...):频数与占比;pd.crosstab():交叉表。
  • Counter(text):粗粒度词频(中文逐字演示)。
  • pd.date_range(...); Series.plot():时间序列折线图(用 matplotlib)。

示例 1:学生成绩的描述统计与直方图¶

  • 目标:一眼看出成绩的中心与离散。
  • 指标:均值、中位数、标准差。
  • 图:直方图(附核密度在进阶中可用 seaborn,但本节仅用 matplotlib)。
In [1]:
import pandas as pd
import matplotlib.pyplot as plt

scores = pd.Series([80, 85, 90, 78, 88, 92, 76, 95])
print("均值:", round(scores.mean(), 2))
print("中位数:", round(scores.median(), 2))
print("标准差:", round(scores.std(), 2))

plt.figure()
plt.hist(scores, bins=5)  # 直方图
plt.title("学生成绩分布")
plt.xlabel("成绩")
plt.ylabel("人数")
plt.show()
C:\Users\Zhouq\AppData\Roaming\Python\Python39\site-packages\pandas\core\computation\expressions.py:21: UserWarning: Pandas requires version '2.8.4' or newer of 'numexpr' (version '2.8.3' currently installed).
  from pandas.core.computation.check import NUMEXPR_INSTALLED
C:\Users\Zhouq\AppData\Roaming\Python\Python39\site-packages\pandas\core\arrays\masked.py:60: UserWarning: Pandas requires version '1.3.6' or newer of 'bottleneck' (version '1.3.5' currently installed).
  from pandas.core import (
均值: 85.5
中位数: 86.5
标准差: 6.93
C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 23398 (\N{CJK UNIFIED IDEOGRAPH-5B66}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 29983 (\N{CJK UNIFIED IDEOGRAPH-751F}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 25104 (\N{CJK UNIFIED IDEOGRAPH-6210}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 32489 (\N{CJK UNIFIED IDEOGRAPH-7EE9}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 20998 (\N{CJK UNIFIED IDEOGRAPH-5206}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 24067 (\N{CJK UNIFIED IDEOGRAPH-5E03}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 20154 (\N{CJK UNIFIED IDEOGRAPH-4EBA}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 25968 (\N{CJK UNIFIED IDEOGRAPH-6570}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)

示例 2:调查问卷的频数与交叉表分析¶

  • 频数与占比常用于问卷单题统计;交叉表用于两个分类变量的关系展示。
In [2]:
import pandas as pd

df = pd.DataFrame({
    '性别': ['男','女','女','男','女','男'],
    '职业': ['学生','教师','学生','教师','学生','学生']
})

# 频数与占比
print("职业频数:")
print(df['职业'].value_counts())
print("\n职业占比:")
print(df['职业'].value_counts(normalize=True).round(3))

# 交叉表
print("\n性别×职业 交叉表:")
print(pd.crosstab(df['性别'], df['职业']))
职业频数:
职业
学生    4
教师    2
Name: count, dtype: int64

职业占比:
职业
学生    0.667
教师    0.333
Name: proportion, dtype: float64

性别×职业 交叉表:
职业  学生  教师
性别        
女    2   1
男    2   1

示例 3:文本词频(逐字统计)¶

入门演示:按字统计《春晓》的字频。进阶可做分词、去停用词、情感分析。

In [3]:
from collections import Counter

text = "春眠不觉晓,处处闻啼鸟。夜来风雨声,花落知多少。"
words = list(text)  # 入门:逐字统计;进阶可换成分词结果
freq = Counter(words)

# 打印前若干高频字
for k, v in list(freq.items())[:10]:
    print(f"{k}: {v}")
春: 1
眠: 1
不: 1
觉: 1
晓: 1
,: 2
处: 2
闻: 1
啼: 1
鸟: 1

示例 4:历史数据的时间序列折线图¶

  • 目标:观察年度趋势与波动。
  • 做法:date_range 生成日期索引 + 折线图。
In [5]:
import pandas as pd
import matplotlib.pyplot as plt

# 设置支持中文的字体,例如黑体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 或者 'Microsoft YaHei', 'FangSong', 'KaiTi' 等
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

dates = pd.date_range(start='2023-01', periods=12, freq='M')
values = [120, 130, 125, 140, 160, 150, 170, 180, 160, 150, 140, 130]
ts = pd.Series(values, index=dates)

plt.figure()
ts.plot(marker='o')
plt.title("年度历史数据趋势")
plt.ylabel("数值")
plt.xlabel("时间")
plt.show()
C:\Users\Zhouq\AppData\Local\Temp\ipykernel_24276\3117942153.py:8: FutureWarning: 'M' is deprecated and will be removed in a future version, please use 'ME' instead.
  dates = pd.date_range(start='2023-01', periods=12, freq='M')

(可选进阶)PCA 降维与 KMeans 聚类(仅当 scikit-learn 可用)¶

  • 场景:高维指标想要压缩与解释(PCA),或自动分组(聚类)。
In [6]:
import numpy as np

# 构造小数据:两个相关变量 + 少量噪声
np.random.seed(0)
X = np.column_stack([
    np.linspace(0, 10, 30),
    np.linspace(0, 10, 30) + np.random.normal(0, 1, 30)
])

try:
    from sklearn.decomposition import PCA
    from sklearn.cluster import KMeans

    pca = PCA(n_components=1).fit(X)
    X1 = pca.transform(X)  # 压成 1 维
    kmeans = KMeans(n_clusters=2, n_init=10, random_state=0).fit(X)
    labels = kmeans.labels_

    print("PCA:第一主成分方差解释率 ≈", round(pca.explained_variance_ratio_[0], 3))
    print("KMeans:簇标签(前10项)", labels[:10])
except Exception as e:
    print("(提示)未检测到 scikit-learn,跳过 PCA/KMeans 演示。")
PCA:第一主成分方差解释率 ≈ 0.967
KMeans:簇标签(前10项) [1 1 1 1 1 1 1 1 1 1]

注意事项(常见坑)¶

  1. 方法选型与问题匹配:描述统计看全貌;假设检验看差异是否“足够大”;回归/分类用于预测;聚类用于发现结构。
  2. 可视化要素:一图一义;坐标/标题/单位清晰;避免过度装饰。
  3. 数据清洗先行:缺失/重复/异常会直接影响统计与图表。
  4. 相关≠因果:需要设计研究或使用因果推断方法进一步验证。
  5. 报告习惯:同时报告样本量、统计量与解释;对假设、限制与数据来源保持透明。

练习(建议先做再看答案)¶

练习 1:描述统计 + 直方图
数据:[72, 85, 90, 66, 88, 92, 75, 81, 77, 89]

  • 计算均值/中位数/标准差;画直方图并写一句话解读。

练习 2:频数与交叉表
数据:

性别:  男, 女, 女, 男, 女, 男, 女, 男
职业:  学生, 学生, 教师, 教师, 学生, 学生, 教师, 教师
  • 统计“职业”的频数与占比;给出“性别×职业”的交叉表。

练习 3:文本词频
文本:自拟一段 30–100 字的中文文本;统计字符频次并打印前 10 个。

练习 4:时间序列折线
构造 2024 年 12 个月的月度序列(自拟数值),画折线并写一句话描述趋势。

In [ ]:
# === 在此动手做题(你可以多建几个单元格)===
import pandas as pd
import matplotlib.pyplot as plt
from collections import Counter
import numpy as np

# 练习 1:描述统计 + 直方图


# 练习 2:频数与交叉表


# 练习 3:文本词频(打印前10个)


# 练习 4:时间序列折线(2024-01 到 2024-12)

参考答案(对照自检)¶

说明:答案仅示意,真实报告请用自然语言解释数值含义。

In [7]:
# 练习 1 参考答案
scores2 = pd.Series([72, 85, 90, 66, 88, 92, 75, 81, 77, 89])
print("均值:", round(scores2.mean(), 2))
print("中位数:", round(scores2.median(), 2))
print("标准差:", round(scores2.std(), 2))

plt.figure()
plt.hist(scores2, bins=5)
plt.title("练习1:成绩分布")
plt.xlabel("成绩")
plt.ylabel("人数")
plt.show()

print("一句话解读:均值与中位数接近,分布较集中;少量中高分拉高整体水平。")
均值: 81.5
中位数: 83.0
标准差: 8.73
一句话解读:均值与中位数接近,分布较集中;少量中高分拉高整体水平。
In [8]:
# 练习 2 参考答案
df2 = pd.DataFrame({
    '性别': ['男','女','女','男','女','男','女','男'],
    '职业': ['学生','学生','教师','教师','学生','学生','教师','教师']
})
print("职业频数:\n", df2['职业'].value_counts())
print("\n职业占比:\n", df2['职业'].value_counts(normalize=True).round(3))
print("\n性别×职业 交叉表:\n", pd.crosstab(df2['性别'], df2['职业']))
职业频数:
 职业
学生    4
教师    4
Name: count, dtype: int64

职业占比:
 职业
学生    0.5
教师    0.5
Name: proportion, dtype: float64

性别×职业 交叉表:
 职业  学生  教师
性别        
女    2   2
男    2   2
In [9]:
# 练习 3 参考答案
text2 = "数据让我们更好地理解社会,但方法选择与解释同样重要。"
freq2 = Counter(list(text2))
for ch, cnt in list(freq2.items())[:10]:
    print(f"{ch}: {cnt}")
数: 1
据: 1
让: 1
我: 1
们: 1
更: 1
好: 1
地: 1
理: 1
解: 2
In [10]:
# 练习 4 参考答案
dates2 = pd.date_range(start='2024-01', periods=12, freq='M')
values2 = [100,105,110,120,130,125,135,140,138,132,128,126]
ts2 = pd.Series(values2, index=dates2)

plt.figure()
ts2.plot(marker='o')
plt.title("练习4:2024 月度趋势")
plt.ylabel("数值")
plt.xlabel("时间")
plt.show()

print("一句话解读:总体上半年稳步上升,三季度小幅波动,四季度略有回落。")
C:\Users\Zhouq\AppData\Local\Temp\ipykernel_24276\3170565209.py:2: FutureWarning: 'M' is deprecated and will be removed in a future version, please use 'ME' instead.
  dates2 = pd.date_range(start='2024-01', periods=12, freq='M')
一句话解读:总体上半年稳步上升,三季度小幅波动,四季度略有回落。

小结¶

  • 选择方法的关键:问题→指标→方法→解释。
  • 入门阶段优先掌握:描述统计、频数/交叉表、折线/柱状图;再逐步引入假设检验、回归、聚类与降维。
  • 任何结果都需要结合研究情境做解释,并说明数据来源与限制。

下一步建议:把本节的输出拼成一个“快速报告模板”(表格 + 图 + 文字解读)。