当前位置:首页>python>Python 单细胞分析进阶:详细理解 AnnData 数据结构

Python 单细胞分析进阶:详细理解 AnnData 数据结构

  • 2026-08-20 23:06:23
Python 单细胞分析进阶:详细理解 AnnData 数据结构

Python 单细胞分析进阶:详细理解 AnnData 数据结构

单细胞 Python 分析系列第 4 篇前面我们已经学习了 Python 基础语法、条件语句、循环语句、函数以及 pandas 数据框操作。从这一篇开始,我们正式进入 Python 单细胞分析中最重要的数据对象:AnnData。

很多同学刚开始学习 Scanpy 时,最容易卡在这些名字上:

adata.Xadata.obsadata.varadata.layersadata.rawadata.obsmadata.varmadata.unsadata.obspadata.varp

这些名字看起来比较抽象,但只要记住一个核心思想,后面就会清楚很多:

AnnData 不是一个简单的表达矩阵,而是一个用来统一保存表达矩阵、细胞注释、基因注释和分析结果的对象。

如果说 R 语言中 Seurat 对象是单细胞分析的核心,那么在 Python 生态中,AnnData 就是 Scanpy 分析流程中最核心的数据结构。


本文学习目标

读完这一篇,你应该能够理解:

1. 为什么 Python 单细胞分析需要 AnnData;

2. `adata.X`、`adata.obs`、`adata.var` 分别保存什么;

3. `layers`、`raw`、`obsm`、`uns`、`obsp` 这些结构分别有什么用途;

4. 单样本单细胞基础分析流程中,每一步会改变 AnnData 的哪个槽位;

5. 初学者在使用 AnnData 时最容易踩哪些坑。


    01 为什么需要 AnnData?

    单细胞数据并不只是一个表达矩阵。

    一个完整的单细胞分析对象,通常至少包括:

    • 每个细胞的表达矩阵;
    • 每个细胞的 barcode、样本来源、分组、细胞类型等注释信息;
    • 每个基因的 gene symbol、gene id、高变基因标记等信息;
    • PCA、UMAP、tSNE 等降维结果;
    • Leiden / Louvain 聚类结果;
    • 细胞之间的邻接图;
    • 差异基因分析结果;
    • 如果是空间转录组,还包括空间坐标和组织图片。

    如果把这些信息全部分开保存,分析过程会非常混乱。

    例如,你可能需要同时维护:

    表达矩阵.csv细胞注释.csv基因注释.csvUMAP坐标.csv聚类结果.csv差异基因结果.csv

    这样做不仅容易出错,也很难保证不同文件中的细胞顺序、基因顺序完全一致。

    因此,AnnData 的作用就是:

    把单细胞分析中产生的各种信息,统一装进一个对象里。

    这样后续做质控、降维、聚类、可视化和保存结果时,都可以围绕一个对象完成。


    02 什么是类和对象?

    在 Python 中,很多分析结果不是普通的数据框,而是一个“对象”。

    例如:

    import scanpy as scadata = sc.read_h5ad(”learndata.h5ad”)adata

    这里的 adata 就是一个 AnnData 对象。

    它有点类似于 R 语言中的 Seurat 对象,也可以粗略理解为 R 中的 S4 对象。这个对象里面不仅有表达矩阵,还有细胞信息、基因信息、降维结果和分析结果。

    可以简单理解为:

    AnnData 对象 = 表达矩阵 + 细胞信息 + 基因信息 + 分析结果

    查看对象时,通常会看到类似结果:

    AnnData object with n_obs × n_vars = 3000 × 20000 obs: ... var: ... uns: ... obsm: ... layers: ... obsp: ...

    其中:

    n_obs = observation,观察值数量,通常是细胞数或空间 spot 数n_vars = variable,变量数量,通常是基因数

    对于单细胞 RNA-seq:

    obs = cellvar = gene

    对于空间转录组 Visium 数据:

    obs = spotvar = gene

    03 Python 单细胞分析生态:Scverse

    Python 单细胞分析常用的是Scverse生态。

    可以简单类比:

    R 语言单细胞生态:Seurat / BioconductorPython 单细胞生态:Scanpy / AnnData / Scverse

    常见工具包括:

    图 1 可以帮助大家建立一个整体认识:

    AnnData 负责“装数据”,Scanpy 负责“做分析”,MuData / SpatialData / Squidpy / scvi-tools 负责扩展不同应用场景。


    04 AnnData 的整体结构

    AnnData 全称是:

    Annotated Data

    也就是“带注释的数据”。

    它最核心的结构可以理解为:

    adata.X 表达矩阵adata.obs 细胞注释信息adata.var 基因注释信息adata.layers 不同版本表达矩阵adata.raw 原始表达备份adata.obsm 细胞层面的多维结果adata.varm 基因层面的多维结果adata.uns 非结构化结果adata.obsp 细胞-细胞关系矩阵adata.varp 基因-基因关系矩阵

    可以把 AnnData 想象成一个整理好的“数据收纳箱”。不同的信息放在不同的槽位中,后续分析和可视化时,Scanpy 会自动从这些槽位中读取对应内容。


    05 准备环境和读取数据

    本篇使用 Scanpy 作为示例。

    import scanpy as scimport anndata as adimport pandas as pdimport numpy as npimport matplotlib.pyplot as plt

    读取 .h5ad 文件:

    adata = sc.read_h5ad(”learndata.h5ad”)adata

    读取后建议先运行:

    adata.var_names_make_unique()

    这一步的作用是让基因名唯一,避免后续分析中因为重复基因名产生报错或 warning。

    如果你读取的是 10X mtx 格式,可以使用:

    adata = sc.read_10x_mtx( ”filtered_feature_bc_matrix/”, var_names=”gene_symbols”, cache=True)adata.var_names_make_unique()adata

    如果你读取的是 10X h5 格式,可以使用:

    adata = sc.read_10x_h5(”filtered_feature_bc_matrix.h5”)adata.var_names_make_unique()adata

    06 adata.X:表达矩阵

    adata.X 是 AnnData 中最核心的部分,用来保存表达矩阵。

    adata.X

    查看表达矩阵维度:

    adata.X.shape

    AnnData 中表达矩阵的方向是:

    行:细胞 / spot列:基因

    也就是:

    cells × genes

    这一点非常重要。很多 R 语言分析中,我们更常见的是:

    genes × cells

    所以在 Python 单细胞分析中,一定要注意矩阵方向。

    可以查看对象中的细胞数和基因数:

    adata.n_obsadata.n_vars

    也可以查看细胞名和基因名:

    adata.obs_namesadata.var_names

    07 稀疏矩阵和普通矩阵

    单细胞表达矩阵中有大量 0 值,因此通常用稀疏矩阵保存。

    查看:

    adata.X

    如果显示类似:

    Compressed Sparse Row sparse matrix

    说明 adata.X 是稀疏矩阵。

    如果想转成普通矩阵,可以使用:

    dense_matrix = adata.X.toarray()

    如果想转成 pandas 数据框:

    expr_df = adata.to_df()expr_df.head()

    但是要注意:真实单细胞数据往往很大,直接转成普通矩阵可能会占用大量内存。

    不建议随便对大对象运行:

    adata.X.toarray()

    更推荐只提取少量基因:

    adata[:, [”Dusp3”, ”Dusp5”]].to_df()

    如果是人类数据,基因名通常是大写:

    adata[:, [”DUSP3”, ”DUSP5”]].to_df()

    08 adata.obs:细胞注释信息

    adata.obs 相当于 Seurat 对象中的 metadata。

    查看:

    adata.obs.head()

    查看有哪些列:

    adata.obs.columns

    常见内容包括:

    样本来源实验分组细胞类型n_countsn_genes线粒体比例聚类编号批次信息

    例如计算质控指标:

    adata.var[”mt”] = adata.var_names.str.startswith(”mt-”)sc.pp.calculate_qc_metrics( adata, qc_vars=[”mt”], inplace=True)

    运行后,adata.obs 中会增加:

    n_genes_by_countstotal_countstotal_counts_mtpct_counts_mt

    这些都是每个细胞的质控信息。


    09 在 adata.obs 中添加新信息

    adata.obs 本质上是一个 pandas DataFrame,因此可以像操作普通数据框一样添加新列。

    例如标记线粒体比例较高的细胞:

    adata.obs[”high_mt”] = adata.obs[”pct_counts_mt”] > 20

    也可以添加分组信息:

    adata.obs[”group”] = ”sample1”

    如果有多个样本,可以根据样本名映射分组:

    adata.obs[”group”] = adata.obs[”sample”].map({ ”sample1”: ”Control”, ”sample2”: ”Disease”})

    查看细胞名字:

    adata.obs_names

    通常 adata.obs_names 就是每个细胞的 barcode。


    10 adata.var:基因注释信息

    adata.var 保存的是基因层面的信息。

    查看:

    adata.var.head()

    查看基因名:

    adata.var_names

    查看有哪些基因注释列:

    adata.var.columns

    常见内容包括:

    gene_idsfeature_typeshighly_variablemeansdispersionsmt

    比如下面这句:

    adata.var[”mt”] = adata.var_names.str.startswith(”mt-”)

    就是在 adata.var 中添加一列,标记哪些基因是线粒体基因。

    对于人类数据,线粒体基因通常是大写:

    adata.var[”mt”] = adata.var_names.str.startswith(”MT-”)

    对于小鼠数据,线粒体基因通常是小写:

    adata.var[”mt”] = adata.var_names.str.startswith(”mt-”)

    11 修改基因索引时要谨慎

    有些数据读取后,adata.var_names 是 gene symbol,例如:

    ActbGapdhAlb

    而 adata.var["gene_ids"] 是 Ensembl ID,例如:

    ENSMUSG00000029580

    如果确实想把基因名改成 Ensembl ID,建议先保存原来的 gene symbol:

    adata.var[”gene_symbol”] = adata.var_namesadata.var_names = adata.var[”gene_ids”]

    但是对于初学者,我更建议保留 gene symbol 作为 var_names。因为后面画图时使用 gene symbol 更直观:

    sc.pl.umap(adata, color=”Dusp5”)

    12 adata.layers:保存不同版本的表达矩阵

    adata.layers 非常重要。

    在分析过程中,表达矩阵会经历多个版本:

    原始 counts归一化数据log-normalized 数据scale 后的数据

    如果所有步骤都覆盖到 adata.X 中,后面很容易不知道当前的 adata.X 到底是什么。

    因此,推荐使用 layers 保存不同版本的数据。

    在归一化之前保存原始 counts:

    adata.layers[”counts”] = adata.X.copy()

    归一化和 log 转换:

    sc.pp.normalize_total(adata, target_sum=1e4)sc.pp.log1p(adata)adata.layers[”lognorm”] = adata.X.copy()

    查看 layers:

    adata.layers

    使用某一个 layer 画图:

    sc.pl.matrixplot( adata, var_names=[”Dusp3”, ”Dusp5”], groupby=”clusters”, layer=”lognorm”)

    这里建议大家养成一个习惯:

    不要随便覆盖 adata.X,关键步骤前先保存到 layers。


    13 adata.raw:保存原始表达备份

    除了 layers,AnnData 还有一个常用结构叫 raw。

    一般可以在筛选高变基因之前保存:

    adata.raw = adata.copy()

    它的作用是保留一份原始表达信息。例如后面只保留了高变基因,但画图时还想查看其他基因,就可以从 adata.raw 中调用。

    需要注意:adata.raw 通常只是用于保存表达备份,不建议在整个流程中反复修改。


    14 adata.obsm:存储降维坐标

    adata.obsm 用来存储每个细胞对应的多维信息。

    查看:

    adata.obsm.keys()

    常见内容包括:

    X_pcaX_umapX_tsnespatial

    例如 PCA 结果:

    adata.obsm[”X_pca”]

    UMAP 结果通常保存在:

    adata.obsm[”X_umap”]

    所以当我们运行:

    sc.tl.umap(adata)

    Scanpy 实际上是把 UMAP 坐标保存到了:

    adata.obsm[”X_umap”]

    画图时:

    sc.pl.umap(adata, color=”clusters”)

    本质上就是从 adata.obsm["X_umap"] 中取坐标。

    如果是空间转录组,空间坐标通常保存在:

    adata.obsm[”spatial”]

    15 adata.varm:存储基因层面的多维信息

    adata.varm 和 obsm 类似,但它是针对基因的。

    例如 PCA 中每个基因对主成分的贡献,也就是 loading,可能会保存在:

    adata.varm[”PCs”]

    查看:

    adata.varm.keys()

    对于初学者来说,varm 使用频率没有 obsm 高,但需要知道它保存的是基因层面的多维结果。


    16 adata.uns:存储非结构化信息

    adata.uns 是一个字典结构,用来保存各种非结构化结果。

    查看:

    adata.uns

    或者:

    adata.uns_keys()

    注意这里要加括号。

    常见内容包括:

    neighborsumapleidenrank_genes_groupslog1pspatial

    例如运行聚类:

    sc.tl.leiden(adata, key_added=”clusters”)

    聚类结果会保存在:

    adata.obs[”clusters”]

    而聚类颜色等信息可能保存在:

    adata.uns[”clusters_colors”]

    运行差异分析:

    sc.tl.rank_genes_groups( adata, groupby=”clusters”, method=”wilcoxon)

    差异分析结果会保存在:

    adata.uns[”rank_genes_groups”]

    提取差异基因结果:

    deg = sc.get.rank_genes_groups_df( adata, group=None)deg.head()

    17 adata.obsp:细胞之间的关系矩阵

    adata.obsp 用来存储细胞和细胞之间的关系矩阵。

    查看:

    adata.obsp.keys()

    当我们运行:

    sc.pp.neighbors(adata)

    Scanpy 会构建细胞之间的近邻图,结果通常保存在:

    adata.obsp[”distances”]adata.obsp[”connectivities”]

    其中:

    distances:细胞之间的距离connectivities:细胞之间的连接强度

    后面的 UMAP 和 Leiden 聚类都依赖这个近邻图。

    也就是说,Scanpy 基础流程一般是:

    PCA → neighbors → UMAP / Leiden

    18 adata.varp:基因之间的关系矩阵

    adata.varp 和 obsp 类似,但它保存的是基因与基因之间的关系。

    例如:

    基因相关性矩阵基因共表达网络基因距离矩阵

    在基础单细胞分析中,varp 不一定经常使用,但在基因网络分析、共表达分析中可能会用到。


    19 结合单样本分析流程理解 AnnData 变化

    理解 AnnData 最好的方法,就是把它和单细胞分析流程结合起来。

    下面用一个基础单样本流程,把 AnnData 每一步发生了什么讲清楚。


    19.1 读取数据

    adata = sc.read_h5ad(”learndata.h5ad”)adata.var_names_make_unique()adata

    此时主要有:

    adata.X:表达矩阵adata.obs:细胞信息adata.var:基因信息

    19.2 计算质控指标

    adata.var[”mt”] = adata.var_names.str.startswith(”mt-”)sc.pp.calculate_qc_metrics( adata, qc_vars=[”mt”], inplace=True)

    运行后,adata.obs 会增加质控指标:

    total_countsn_genes_by_countspct_counts_mt

    这一步主要改变的是:

    adata.obsadata.var

    19.3 质控可视化

    质控指标计算完成后,可以先画图观察数据分布:

    fig, axs = plt.subplots(14, figsize=(154))axs[0].hist(adata.obs[”total_counts”], bins=50)axs[0].set_title(”total_counts”)axs[1].hist(adata.obs[”total_counts”][adata.obs[”total_counts”] < 10000], bins=40)axs[1].set_title(”total_counts < 10000”)axs[2].hist(adata.obs[”n_genes_by_counts”], bins=60)axs[2].set_title(”n_genes_by_counts”)axs[3].hist(adata.obs[”pct_counts_mt”], bins=60)axs[3].set_title(”pct_counts_mt”)plt.tight_layout()plt.show()

    这一步不会改变 AnnData 的主要结构,只是帮助我们确定后面的过滤阈值。


    19.4 质控过滤

    sc.pp.filter_cells(adata, min_counts=5000)sc.pp.filter_cells(adata, max_counts=35000)adata = adata[adata.obs[”pct_counts_mt”] < 20].copy()

    这一步会减少细胞数量,也就是:

    adata.n_obs 变少adata.X 行数变少adata.obs 行数变少

    过滤基因:

    sc.pp.filter_genes(adata, min_cells=10)

    这一步会减少基因数量,也就是:

    adata.n_vars 变少adata.X 列数变少adata.var 行数变少

    查看过滤后的细胞数量:

    print(f”#cells after filter: {adata.n_obs}”)

    19.5 保存原始 counts

    在归一化之前,建议保存原始矩阵:

    adata.layers[”counts”] = adata.X.copy()

    此时:

    adata.layers[”counts”] 保存原始 counts

    19.6 归一化和 log 转换

    sc.pp.normalize_total(adata, target_sum=1e4)sc.pp.log1p(adata)adata.layers[”lognorm”] = adata.X.copy()

    这一步会修改:

    adata.X

    因此保存到 layers["lognorm"] 是一个好习惯。


    19.7 高变基因

    sc.pp.highly_variable_genes( adata, flavor=”seurat”, n_top_genes=2000)

    这一步主要在 adata.var 中增加:

    highly_variablemeansdispersionsdispersions_norm

    可以查看高变基因:

    adata.var[adata.var[”highly_variable”]].head()

    也可以画高变基因图:

    sc.pl.highly_variable_genes(adata)

    19.8 PCA 降维

    sc.pp.pca(adata)

    运行后,结果通常保存到:

    adata.obsm[”X_pca”]adata.varm[”PCs”]adata.uns[”pca”]

    也就是说:

    细胞的 PCA 坐标 → obsm基因的 PCA loading → varmPCA 参数和方差信息 → uns

    可以查看 PCA 结果:

    adata.obsm[”X_pca”].shape

    19.9 构建邻接图

    sc.pp.neighbors(adata)

    运行后,会生成:

    adata.obsp[”distances”]adata.obsp[”connectivities”]adata.uns[”neighbors”]

    这一步是后续 UMAP 和聚类的基础。


    19.10 UMAP 降维

    sc.tl.umap(adata)

    运行后,UMAP 坐标保存在:

    adata.obsm[”X_umap”]

    画图:

    sc.pl.umap( adata, color=[”total_counts”, ”n_genes_by_counts”])

    19.11 Leiden 聚类

    sc.tl.leiden( adata, key_added=”clusters”)

    运行后,聚类结果保存在:

    adata.obs[”clusters”]

    画图:

    sc.pl.umap( adata, color=[”clusters”])

    这时 adata.obs 中就有了每个细胞所属的 cluster。


    19.12 marker 基因识别

    基础聚类完成后,可以寻找每个 cluster 的 marker 基因:

    sc.tl.rank_genes_groups( adata, groupby=”clusters”, method=”wilcoxon)

    结果会保存到:

    adata.uns[”rank_genes_groups”]

    提取成数据框:

    markers = sc.get.rank_genes_groups_df( adata, group=None)markers.head()

    保存结果:

    markers.to_csv(”cluster_markers.csv”, index=False)

    19.13 保存分析结果

    adata.write_h5ad(”single_sample_processed.h5ad”)

    下次可以直接读取:

    adata = sc.read_h5ad(”single_sample_processed.h5ad”)

    20 一个总结表:每一步改变了什么?


    21 完整单样本基础流程代码

    下面放一份相对完整的单样本基础流程代码,适合作为后续练习模板。

    import scanpy as scimport pandas as pdimport numpy as npimport matplotlib.pyplot as plt# 1. 读取数据adata = sc.read_h5ad(”learndata.h5ad”)adata.var_names_make_unique()# 2. 标记线粒体基因# 小鼠数据通常是 mt-,人类数据通常是 MT-adata.var[”mt”] = adata.var_names.str.startswith(”mt-”)# 3. 计算 QC 指标sc.pp.calculate_qc_metrics( adata, qc_vars=[”mt”], inplace=True)# 4. 查看对象print(adata)print(adata.obs.head())print(adata.var.head())# 5. 质控过滤sc.pp.filter_cells(adata, min_counts=5000)sc.pp.filter_cells(adata, max_counts=35000)adata = adata[adata.obs[”pct_counts_mt”] < 20].copy()sc.pp.filter_genes(adata, min_cells=10)print(f”#cells after filter: {adata.n_obs}”)print(f”#genes after filter: {adata.n_vars}”)# 6. 保存原始 countsadata.layers[”counts”] = adata.X.copy()# 7. 标准化和 log 转换sc.pp.normalize_total(adata, target_sum=1e4)sc.pp.log1p(adata)adata.layers[”lognorm”] = adata.X.copy()# 8. 高变基因sc.pp.highly_variable_genes( adata, flavor=”seurat”, n_top_genes=2000)# 9. PCA / 邻接图 / UMAP / 聚类sc.pp.pca(adata)sc.pp.neighbors(adata)sc.tl.umap(adata)sc.tl.leiden(adata, key_added=”clusters”)# 10. 可视化sc.pl.umap( adata, color=[”total_counts”, ”n_genes_by_counts”, ”pct_counts_mt”, ”clusters”], wspace=0.4)# 11. marker 基因sc.tl.rank_genes_groups( adata, groupby=”clusters”, method=”wilcoxon”)markers = sc.get.rank_genes_groups_df( adata, group=None)markers.to_csv(”cluster_markers.csv”, index=False)# 12. 保存对象adata.write_h5ad(”single_sample_processed.h5ad”)

    22 初学者最容易踩的坑

    22.1 重复基因名

    很多公开数据中可能存在重复基因名。读取数据后建议先运行:

    adata.var_names_make_unique()

    否则后续分析可能会出现 warning 或报错。


    22.2 把 .copy 写成 .copy()

    错误写法:

    adata1 = adata.copy

    正确写法:

    adata1 = adata.copy()

    少了括号,adata1 不是复制出来的新对象,而是一个方法本身。


    22.3 切片后忘记 .copy()

    AnnData 中切片后得到的对象可能只是 view,不是真正独立的 copy。

    不推荐:

    adata_sub = adata[adata.obs[”pct_counts_mt”] < 20]

    推荐:

    adata_sub = adata[adata.obs[”pct_counts_mt”] < 20].copy()

    尤其是后面要修改 adata_sub.obs 或 adata_sub.X 时,建议一定加 .copy()。


    22.4 不清楚当前 adata.X 是什么

    分析流程中,adata.X 经常会被修改。因此建议在关键步骤保存不同版本:

    adata.layers[”counts”] = adata.X.copy()sc.pp.normalize_total(adata, target_sum=1e4)sc.pp.log1p(adata)adata.layers[”lognorm”] = adata.X.copy()

    这样后面需要原始 counts 或 lognorm 数据时,就不会混乱。


    22.5 线粒体基因大小写写错

    人类数据:

    adata.var[”mt”] = adata.var_names.str.startswith(”MT-”)

    小鼠数据:

    adata.var[”mt”] = adata.var_names.str.startswith(”mt-”)

    如果大小写写错,pct_counts_mt 可能全部为 0 或计算异常。


    22.6 随意把大矩阵转成普通矩阵

    不推荐对大数据直接运行:

    adata.X.toarray()

    因为这样可能会占用大量内存。

    更推荐:

    adata[:, [”Dusp3”, ”Dusp5”]].to_df()

    23 保存和读取 h5ad 文件

    分析完成后,可以保存:

    adata.write_h5ad(”single_sample_processed.h5ad”)

    下次直接读取:

    adata = sc.read_h5ad(”single_sample_processed.h5ad”)

    .h5ad 的好处是可以把 AnnData 对象中的大多数内容一起保存,包括:

    表达矩阵细胞注释基因注释降维结果聚类结果邻接图差异分析结果

    所以它非常适合作为 Python 单细胞分析的中间结果文件。


    24 AnnData 和 Seurat 对象的简单类比

    对于熟悉 Seurat 的同学,可以用下面这个表帮助理解:

    这个类比并不是完全一一对应,但对于初学者理解 AnnData 很有帮助。


    25 本篇小结

    这一篇主要介绍了 Python 单细胞分析中最核心的数据结构:AnnData。

    可以用一句话总结:

    AnnData 是 Python 单细胞分析中用来统一存储表达矩阵、细胞注释、基因注释和分析结果的核心对象。

    其中最重要的结构包括:

    adata.X 表达矩阵adata.obs 细胞信息adata.var 基因信息adata.layers 多版本表达矩阵adata.obsm 细胞降维结果adata.varm 基因多维结果adata.uns 非结构化分析结果adata.obsp 细胞关系矩阵adata.varp 基因关系矩阵adata.raw 原始表达备份

    对于初学者来说,建议重点掌握:

    X、obs、var、layers、obsm、uns、obsp

    这几个结构理解清楚之后,再看 Scanpy 的单细胞分析流程就会容易很多。


    26 学习五问

    最后留 5 个问题,帮助大家检查自己是否真正理解了 AnnData:

      如果这 5 个问题你都能回答出来,说明你已经理解了 AnnData 的核心结构。


      27 下期预告

      下一篇我们可以继续介绍:

      不同格式单细胞数据的读取方式,以及单细胞基础分析 pipeline。

      包括:

      10X mtx 文件filtered_feature_bc_matrix.h5h5ad 文件loom 文件csv / tsv 表达矩阵空间转录组 Visium 数据

      然后进入完整的单样本基础分析流程:

      读取数据质控过滤标准化高变基因PCA邻接图UMAP聚类marker 基因识别细胞类型注释

      如果你已经读到这里,说明你已经正式从 Python 基础迈入单细胞分析的核心阶段了。


      本篇关键词:Python 单细胞分析、Scanpy、AnnData、adata.X、adata.obs、adata.var、layers、obsm、uns、obsp。

      最新文章

      随机文章

      基本 文件 流程 错误 SQL 调试
      1. 请求信息 : 2026-08-21 23:28:03 HTTP/2.0 GET : https://f.mffb.com.cn/a/504550.html
      2. 运行时间 : 0.226976s [ 吞吐率:4.41req/s ] 内存消耗:4,795.94kb 文件加载:140
      3. 缓存信息 : 0 reads,0 writes
      4. 会话信息 : SESSION_ID=a184dbbc0739faead664d4737ceed600
      1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
      2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
      3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
      4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
      5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
      6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
      7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
      8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
      9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
      10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
      11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
      12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
      13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
      14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
      15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
      16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
      17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
      18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
      19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
      20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
      21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
      22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
      23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
      24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
      25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
      26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
      27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
      28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
      29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
      30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
      31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
      32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
      33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
      34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
      35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
      36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
      37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
      38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
      39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
      40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
      41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
      42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
      43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
      44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
      45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
      46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
      47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
      48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
      49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
      50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
      51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
      52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
      53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
      54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
      55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
      56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
      57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
      58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
      59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
      60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
      61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
      62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
      63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
      64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
      65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
      66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
      67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
      68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
      69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
      70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
      71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
      72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
      73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
      74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
      75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
      76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
      77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
      78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
      79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
      80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
      81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
      82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
      83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
      84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
      85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
      86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
      87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
      88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
      89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
      90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
      91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
      92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
      93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
      94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
      95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
      96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
      97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
      98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
      99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
      100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
      101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
      102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
      103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
      104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
      105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
      106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
      107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
      108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
      109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
      110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
      111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
      112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
      113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
      114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
      115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
      116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
      117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
      118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
      119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
      120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
      121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
      122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
      123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
      124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
      125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
      126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
      127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
      128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
      129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
      130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
      131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
      132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
      133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
      134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
      135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
      136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
      137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
      138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
      139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
      140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
      1. CONNECT:[ UseTime:0.001184s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
      2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001260s ]
      3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000644s ]
      4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000617s ]
      5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001119s ]
      6. SELECT * FROM `set` [ RunTime:0.000519s ]
      7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001491s ]
      8. SELECT * FROM `article` WHERE `id` = 504550 LIMIT 1 [ RunTime:0.017513s ]
      9. UPDATE `article` SET `lasttime` = 1787326084 WHERE `id` = 504550 [ RunTime:0.031491s ]
      10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000514s ]
      11. SELECT * FROM `article` WHERE `id` < 504550 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000872s ]
      12. SELECT * FROM `article` WHERE `id` > 504550 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.002980s ]
      13. SELECT * FROM `article` WHERE `id` < 504550 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.003864s ]
      14. SELECT * FROM `article` WHERE `id` < 504550 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.006194s ]
      15. SELECT * FROM `article` WHERE `id` < 504550 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.005444s ]
      0.231978s