📚 Termux 无 Root 学习开发系列
阶段一:环境搭建与终端基础 ✅ 已完成
01-05 Termux 安装 → 包管理 → 文件管理 → Vim/tmux
阶段二:编程开发环境 ✅ 已完成
06-09 Python → C/C++ → Node.js → Git
阶段三:网络与远程操作 ✅ 已完成
10-12 SSH → 网络工具 → 网络代理
阶段四:Termux:API 与自动化 ✅ 已完成
13-14 Termux:API → 定时任务与自动化
阶段五:proot-distro 完整 Linux
15 proot-distro:在手机上运行完整 Linux ✓
16 Jupyter Notebook 与数据科学环境(当前篇)
17 桌面环境与 VNC 远程
阶段六至九共 12 篇,后续持续更新
上一篇文章中,我们在手机上用 proot-distro 搭建了完整的 Ubuntu Linux 环境。现在,这个环境将展现它真正的威力——运行 Jupyter Notebook,把你的手机变成一台便携式数据分析工作站。pandas 处理数据、matplotlib 绘制图表、scikit-learn 训练模型,全部在掌中完成。
📋 目录
一、数据科学移动化:手机上的数据分析平台
二、环境搭建:安装数据科学栈
三、中文字体配置:解决 matplotlib 中文乱码
四、Jupyter Notebook 启动与远程访问
五、pandas 数据分析实战:从 CSV 到洞察
六、matplotlib 数据可视化:让数据说话
七、scikit-learn 机器学习入门:手机上训练第一个模型
八、实用技巧与效率工具
一、数据科学移动化:手机上的数据分析平台
提到数据科学,你脑海中浮现的可能是配置强大的台式机或云服务器。但真实的场景往往是这样:通勤地铁上突然想到一个数据思路,午休时想快速验证一个假设,或者躺在床上想复盘今天的业务数据。这些碎片化的时间,如果能用来做数据分析,该多好?
在上一篇搭建的 proot Ubuntu 环境中,我们可以安装完整的 Python 数据科学栈:Jupyter Notebook 提供交互式编程环境,pandas 处理表格数据,matplotlib 绘制可视化图表,scikit-learn 进行机器学习建模。这套组合在桌面端是数据科学家的标准工具链,现在它在你的手机上也能跑。
📌 本篇环境基础
本章基于第 15 篇搭建的 proot-distro Ubuntu 环境。如果你还没有安装,请先完成上一篇的操作:pkg install proot-distro && proot-distro install ubuntu:26.04 && pd sh ubuntu
本篇涉及的软件版本(截至 2026 年 8 月):
| 软件 |
版本 |
发布时间 |
说明 |
| Jupyter Notebook |
7.6.2 |
2026.07 |
基于 JupyterLab 4.6 内核 |
| NumPy |
2.5.2 |
2026.08 |
数组计算基础库 |
| pandas |
3.0.5 |
2026.07 |
数据分析核心库 |
| matplotlib |
3.11.0 |
2026.07 |
2D 可视化绘图库 |
| scikit-learn |
1.9.0 |
2026.08 |
机器学习工具包 |
pandas 3.0 是一个大版本更新,引入了新的 PyArrow 后端和改进的字符串类型系统;NumPy 2.5 进一步优化了 free-threaded Python 支持;scikit-learn 1.9 新增了多项模型评估改进。这些版本在 ARM64 平台上都有良好的支持,可以在手机上流畅运行。
前置:proot-distro Ubuntu
前置:Python pip
难度:高级
二、环境搭建:安装数据科学栈
进入 proot Ubuntu 环境后,我们首先安装数据科学所需的所有 Python 库。整个安装过程分为三步:更新系统、安装编译依赖、安装 Python 包。
2.1 进入 Ubuntu 并更新系统
Bash
# 进入 Ubuntu 容器
pd sh ubuntu
# 更新系统包
apt update && apt upgrade -y
# 安装编译依赖(部分包需要从源码编译)
apt install -y python3-dev python3-pip build-essential \
libopenblas-dev libffi-dev libssl-dev pkg-config
⚠️ 注意
libopenblas-dev 是 NumPy 和 scikit-learn 的 BLAS/LAPACK 依赖,不装会导致安装失败或性能极差。在 ARM64 上,OpenBLAS 能充分利用手机的多核 CPU。
2.2 安装数据科学核心包
使用 pip 一次性安装所有核心包。建议使用 --break-system-packages 标志,因为 Ubuntu 26.04 默认使用 PEP 668 保护机制。
Bash
# 升级 pip 到最新版
pip install --upgrade pip --break-system-packages
# 安装数据科学全家桶
pip install --break-system-packages \
jupyter numpy pandas matplotlib seaborn scikit-learn
# 验证安装
python3 -c "import numpy, pandas, matplotlib, sklearn; print('OK')"
安装过程大约需要 5-10 分钟,取决于手机性能。其中 scikit-learn 会编译部分 C 扩展,是最耗时的部分。如果安装中断,可以单独重装失败的包。
Bash
# 查看已安装版本
python3 -c "
import numpy as np, pandas as pd, matplotlib, sklearn
print(f'NumPy {np.__version__}')
print(f'pandas {pd.__version__}')
print(f'matplotlib {matplotlib.__version__}')
print(f'scikit-learn {sklearn.__version__}')
"
预期输出:NumPy 2.5.2、pandas 3.0.5、matplotlib 3.11.0、scikit-learn 1.9.0。看到这些版本号,意味着你的手机已经具备了桌面级的数据科学能力。
2.3 安装 Jupyter Lab(可选)
除了经典的 Jupyter Notebook,还可以安装更现代的 JupyterLab 界面。JupyterLab 4.6 提供了多标签页、文件浏览器、终端集成等更丰富的功能。
Bash
# 安装 JupyterLab(Notebook 7.6 已内含)
pip install --break-system-packages jupyterlab
# 启动 JupyterLab
jupyter lab --ip=0.0.0.0 --port=8888 --no-browser
三、中文字体配置:解决 matplotlib 中文乱码
在手机上做数据分析,图表中的中文标题和标签经常显示为方框。这是因为 matplotlib 默认不包含中文字体。我们需要安装中文字体并配置 matplotlib 识别它。
3.1 安装中文字体
Bash
# 安装 Noto CJK 字体(Google 出品,覆盖中日韩)
apt install -y fonts-noto-cjk
# 刷新字体缓存
fc-cache -fv
# 验证字体已安装
fc-list | grep -i noto | grep -i cjk
安装完成后,会在 /usr/share/fonts/opentype/noto/ 目录下找到 NotoSansCJK 和 NotoSerifCJK 字体文件。
3.2 配置 matplotlib 中文字体
有两种方式让 matplotlib 使用中文字体:一次性配置(适合临时使用)和永久配置(推荐)。
方式一:代码内配置(推荐)
Python
|
1
2
3
4
5
6
7
8
9
|
import matplotlib.pyplot as plt
from matplotlib import font_manager
font_manager.fontManager.addfont(
'/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc'
)
plt.rcParams['font.sans-serif'] = ['Noto Sans CJK SC']
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示
plt.title('中文标题测试') # 应正常显示
|
方式二:永久配置
Bash
# 创建 matplotlib 配置目录
mkdir -p ~/.config/matplotlib
# 写入字体配置
cat > ~/.config/matplotlib/matplotlibrc << 'EOF'
font.sans-serif: Noto Sans CJK SC, DejaVu Sans
axes.unicode_minus: False
figure.figsize: 10, 6
figure.dpi: 150
EOF
💡 小贴士
matplotlib 3.11 新增了对 TTC(TrueType Collection)字体的原生支持,不再需要手动拆分 TTC 文件为 TTF。直接用 addfont() 指定 .ttc 路径即可。
四、Jupyter Notebook 启动与远程访问
Jupyter Notebook 是一个 Web 应用,启动后会运行一个本地服务器,你通过手机浏览器访问它的界面。关键配置是让服务器监听所有网络接口(--ip=0.0.0.0),这样同一局域网的电脑也能访问。
4.1 设置访问密码
首次使用前,建议设置一个访问密码,避免每次复制 token 的麻烦。
Bash
# 设置 Jupyter 访问密码
jupyter notebook password
# 输入两次密码后,密码会加密存储在 ~/.jupyter/jupyter_server_config.json
4.2 启动 Jupyter 服务
Bash
|
1
2
3
4
5
6
|
# 在 Ubuntu 容器中启动 Jupyter Notebook
jupyter notebook \
--ip=0.0.0.0 \
--port=8888 \
--no-browser \
--notebook-dir=/root/projects
|
启动后,终端会输出类似这样的信息:
Output
# 典型输出:
[I 2026-08-21 10:30:15 Server] Jupyter Notebook 7.6.2
[I 2026-08-21 10:30:15 Server] Serving jupyter notebook from /root/projects
[I 2026-08-21 10:30:15 Server] http://0.0.0.0:8888/notebook
[I 2026-08-21 10:30:15 Server] Use Control-C to stop this server
4.3 手机浏览器访问
打开手机浏览器(推荐 Chrome 或 Firefox),在地址栏输入:
URL
# 本机访问
http://localhost:8888
# 同一局域网电脑访问(替换为手机 IP)
http://192.168.1.100:8888
输入之前设置的密码即可进入 Jupyter 主界面。Notebook 7.6 的界面基于 JupyterLab 4.6 内核重构,支持文件浏览器、多标签页编辑、单元格拖拽等功能。
💡 小贴士
Jupyter Notebook 7.6 的界面与经典版(6.x)完全不同,它采用了 JupyterLab 的前端架构。如果你习惯经典版,可以安装 nbclassic 扩展:pip install nbclassic
4.4 后台运行与开机自启
为了让 Jupyter 在后台持续运行,可以使用 nohup 或 tmux:
Bash
# 方式一:nohup 后台运行
nohup jupyter notebook --ip=0.0.0.0 --port=8888 --no-browser > ~/jupyter.log 2>&1 &
# 方式二:tmux 会话(推荐,可随时查看日志)
tmux new -s jupyter
jupyter notebook --ip=0.0.0.0 --port=8888 --no-browser
# 按 Ctrl-B 然后 D 退出 tmux(Jupyter 继续运行)
# 重新进入:tmux attach -t jupyter
五、pandas 数据分析实战:从 CSV 到洞察
环境就绪后,我们用一组销售数据来演示完整的 pandas 数据分析流程。首先创建一个示例数据集,然后逐步进行读取、清洗、分析和导出。
5.1 生成示例数据
在 Jupyter Notebook 中新建一个 Notebook,输入以下代码生成模拟销售数据并保存为 CSV。
Python
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import pandas as pd
import numpy as np
np.random.seed(42)
dates = pd.date_range('2026-01-01', periods=100)
products = ['手机', '耳机', '充电器', '手机壳', '数据线']
regions = ['华东', '华南', '华北', '西南']
df = pd.DataFrame({
'日期': np.random.choice(dates, 500),
'产品': np.random.choice(products, 500),
'地区': np.random.choice(regions, 500),
'数量': np.random.randint(1, 50, 500),
|
上面只展示了部分行。完整代码还需包含 单价 列(用 random 生成 50-5000 的值),并写入 CSV:
Python
df['单价'] = np.random.uniform(50, 5000, 500).round(2)
df['销售额'] = df['数量'] * df['单价']
# 保存到共享目录(手机可见)
df.to_csv('/sdcard/sales_data.csv', index=False, encoding='utf-8-sig')
print(f'生成 {len(df)} 条记录')
5.2 数据读取与概览
Python
|
1
2
3
4
5
6
7
8
|
# 读取 CSV
df = pd.read_csv('/sdcard/sales_data.csv')
# 查看前 5 行
df.head()
# 基本信息:行数、列名、数据类型、内存占用
df.info()
# 数值列的统计摘要
df.describe()
# 检查缺失值
df.isnull().sum()
|
5.3 数据清洗与转换
Python
|
1
2
3
4
5
6
7
8
9
|
# 转换日期列为 datetime 类型
df['日期'] = pd.to_datetime(df['日期'])
# 提取月份和季度
df['月份'] = df['日期'].dt.month
df['季度'] = df['日期'].dt.quarter
# 删除重复行
df = df.drop_duplicates()
# 填充缺失值(如有)
df['数量'] = df['数量'].fillna(0)
print(f'清洗后 {len(df)} 条记录')
|
⚠️ 常见错误
pandas 3.0 默认使用 PyArrow 作为后端,某些旧的字符串操作方式可能不兼容。如果遇到 AttributeError,检查是否使用了已弃用的 .str 访问器方法。
5.4 分组聚合与透视表
pandas 最强大的功能之一是 groupby 分组聚合和 pivot_table 透视表,用于多维度交叉分析。
Python
|
1
2
3
4
5
6
7
8
|
# 按产品分组,统计总销售额和平均单价
product_stats = df.groupby('产品').agg(
总销售额=('销售额', 'sum'),
订单数=('销售额', 'count'),
平均单价=('单价', 'mean')
).round(2)
print(product_stats.sort_values('总销售额', ascending=False))
|
Python
# 透视表:产品 × 地区,值=销售额总和
pivot = pd.pivot_table(
df, values='销售额',
index='产品', columns='地区',
aggfunc='sum', fill_value=0
)
print(pivot)
六、matplotlib 数据可视化:让数据说话
数据分析的最终成果往往以图表呈现。matplotlib 是 Python 生态中最成熟的绘图库,配合 seaborn 的统计图层,可以创建专业级的可视化。
6.1 折线图:销售额趋势
Python
|
1
2
3
4
5
6
7
8
9
10
|
import matplotlib.pyplot as plt
import seaborn as sns
daily_sales = df.groupby('日期')['销售额'].sum()
plt.figure(figsize=(12, 5))
plt.plot(daily_sales.index, daily_sales.values, color='#be185d')
plt.title('每日销售额趋势', fontsize=16)
plt.xlabel('日期'); plt.ylabel('销售额(元)')
|
6.2 柱状图:各产品销售额对比
Python
|
1
2
3
4
5
6
7
8
|
product_sales = df.groupby('产品')['销售额'].sum().sort_values()
fig, ax = plt.subplots(figsize=(10, 6))
colors = ['#fda4af', '#f43f5e', '#be185d', '#9f1239', '#881337']
bars = ax.bar(product_sales.index, product_sales.values, color=colors)
ax.set_title('各产品销售额对比', fontsize=16)
# 在柱子顶部显示数值
for bar in bars:
|
在柱状图代码中,使用 bar.bar_label() 方法可以在每根柱子顶部显示数值,让图表更直观。
6.3 散点图与热力图
Python
|
1
2
3
4
5
6
7
8
|
# 子图布局:左散点图,右热力图
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))
# 散点图:数量 vs 销售额
ax1.scatter(df['数量'], df['销售额'], alpha=0.5, color='#be185d')
ax1.set_title('数量与销售额关系'); ax1.set_xlabel('数量')
# 热力图:产品 × 地区销售额
sns.heatmap(pivot, annot=True, fmt='.0f', cmap='RdPu', ax=ax2)
ax2.set_title('产品地区销售额热力图')
plt.tight_layout() # 自动调整间距
|
6.4 保存图表到手机存储
Python
# 保存为 PNG(300 DPI 高清)
plt.savefig('/sdcard/sales_dashboard.png', dpi=300, bbox_inches='tight')
plt.show() # 在 Notebook 中显示
# 文件保存到 /sdcard 后,手机相册可直接查看
💡 小贴士
matplotlib 3.11 新增了 constrained_layout 参数,比 tight_layout 效果更好。创建 figure 时指定 plt.figure(constrained_layout=True) 即可自动避免标签重叠。
七、scikit-learn 机器学习入门:手机上训练第一个模型
scikit-learn 1.9 在手机上运行毫无压力。我们用销售数据训练一个简单的随机森林模型,预测产品销售额。这个例子涵盖了数据预处理、模型训练、评估的完整流程。
7.1 特征工程
Python
|
1
2
3
4
5
6
7
8
9
|
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import mean_squared_error, r2_score
# 编码分类变量
le_product = LabelEncoder(); le_region = LabelEncoder()
df['产品编码'] = le_product.fit_transform(df['产品'])
df['地区编码'] = le_region.fit_transform(df['地区'])
|
7.2 训练随机森林模型
Python
|
1
2
3
4
5
6
7
8
9
|
# 特征和标签
features = ['产品编码', '地区编码', '数量', '月份']
X = df[features]; y = df['销售额']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# 训练模型
rf = RandomForestRegressor(n_estimators=100, random_state=42)
rf.fit(X_train, y_train) # 手机上约 3-5 秒
# 预测
y_pred = rf.predict(X_test)
print(f'R² = {r2_score(y_test, y_pred):.4f}')
|
100 棵决策树的随机森林在手机上训练只需几秒钟。R² 分数会告诉你模型拟合的优劣——0.9 以上表示拟合良好。虽然这是模拟数据,但流程和真实场景完全一致。
7.3 特征重要性分析
Python
# 查看特征重要性
importance = pd.DataFrame({
'特征': features,
'重要性': rf.feature_importances_
}).sort_values('重要性', ascending=False)
print(importance)
# 可视化特征重要性
plt.figure(figsize=(8, 4))
plt.barh(importance['特征'], importance['重要性'], color='#be185d')
plt.title('特征重要性排序')
八、实用技巧与效率工具
8.1 nbconvert:命令行执行 Notebook
Jupyter Notebook 7.6 内置了 nbconvert 工具,可以在不打开浏览器的情况下执行 .ipynb 文件并导出结果。这在自动化报告生成场景中非常有用。
Bash
# 执行 Notebook 并输出结果
jupyter nbconvert --to notebook --execute analysis.ipynb \
--output analysis_executed.ipynb --ExecutePreprocessor.timeout=300
# 导出为 HTML 报告
jupyter nbconvert --to html --execute analysis.ipynb \
--output /sdcard/report.html
# 导出为 Markdown
jupyter nbconvert --to markdown analysis.ipynb
8.2 Jupyter 魔法命令
Jupyter 提供了一系列以 % 开头的魔法命令(magic commands),大幅提升交互式编程效率。
Python
# 测量代码执行时间
%%timeit
df.groupby('产品')['销售额'].sum()
# 查看变量内存占用
%memit df
# 内联显示 matplotlib 图表(默认已开启)
%matplotlib inline
# 加载外部 Python 文件为单元格内容
%load /root/projects/utils.py
8.3 性能优化建议
手机端数据科学性能优化清单
1. 数据量大时,用 dtype 指定列类型,减少内存占用
2. 超过 10 万行的数据,用 chunksize 分块读取
3. 避免在 Jupyter 中加载过大的模型,先用小数据验证流程
4. 使用 del 及时释放不需要的大对象
5. matplotlib 图表设置 dpi=150 而非 300,减少渲染压力
6. 训练机器学习模型时,先用 n_jobs=-1 利用全部 CPU 核心
动手练习
🟢 基础练习
1. 安装完整数据科学栈,验证所有包版本正确
2. 配置 matplotlib 中文字体,绘制一个带中文标题的简单折线图
3. 用 pandas 读取一个 CSV 文件(可用手机中的任意数据),执行 head() 和 describe() 观察结果
🟡 进阶练习
1. 生成示例销售数据,用 groupby 和 pivot_table 做多维度分析
2. 绘制包含折线图、柱状图、散点图和热力图的 2x2 子图布局
3. 将分析结果导出为 HTML 报告,保存到 /sdcard 并在手机浏览器中打开
🔴 高级练习
1. 使用 scikit-learn 训练一个分类模型(如 Iris 数据集分类),评估准确率
2. 编写一个 Jupyter Notebook,实现从 CSV 读取到生成可视化报告的完整流程,用 nbconvert 命令行自动执行
3. 搭建一个定时任务(结合第14篇的 cron),每天自动运行 Notebook 并生成 HTML 报告到 /sdcard
知识回顾
Jupyter Notebook 7.6.2
pandas 3.0 数据分析
matplotlib 中文字体配置
分组聚合与透视表
scikit-learn 1.9 机器学习
nbconvert 自动化报告
远程访问与后台运行
下一篇预告
17 桌面环境与 VNC 远程
proot Ubuntu 不仅能跑命令行工具,还能安装完整的图形化桌面环境。下一篇将介绍 XFCE 桌面安装、VNC 服务器配置,让你通过手机或电脑远程操控一个完整的 Linux 桌面。