Python单细胞分析数据结构——AnnData

简介

AnnData ,Annotated Data,是一种类似矩阵的数据,用于单细胞分析,已成为 Python 中该领域的标准数据结构。

AnnData 基于键的存储方式用起来简单,便于可重复性分析,转换为 R 语言的单细胞分析数据结构也十分容易。

假设我们有 n n n 个观测(observations),每个观测可表示为 d d d 维向量,每个维度对应一个变量或特征(variable)。

这个 n × d n \times d n×d 矩阵特殊在于带索引。




安装

pip install anndata




初始化AnnData

  • 使用泊松分布随机生成一个稀疏矩阵,构建 AnnData 对象,表示基因表达数。
  • 构建索引。
  • 构建子集
import numpy as np
import anndata as ad
from scipy.sparse import csr_matrix

counts = csr_matrix(np.random.poisson(1, size=(100, 2000)), dtype=np.float32)  # 泊松分布构建稀疏矩阵
adata = ad.AnnData(counts)  # 初始化AnnData

print(adata)  # 基本统计信息
# AnnData object with n_obs × n_vars = 100 × 2000

print(adata.X)  # 访问稀疏矩阵的数据
#   (0, 1)	1.0
#   (0, 3)	1.0
#   (0, 4)	1.0
# ......

adata.obs_names = [f'Cell_{i:d}' for i in range(adata.n_obs)]
adata.var_names = [f'Gene_{i:d}' for i in range(adata.n_vars)]
print(adata.obs_names[:5])  # 输出前五个观测名,即X轴
print(adata.var_names[:5])  # 输出前五个特征名,即Y轴
# Index(['Cell_0', 'Cell_1', 'Cell_2', 'Cell_3', 'Cell_4'], dtype='object')
# Index(['Gene_0', 'Gene_1', 'Gene_2', 'Gene_3', 'Gene_4'], dtype='object')

print(adata[['Cell_1', 'Cell_10'], ['Gene_5', 'Gene_1900']])  # 构建子集
# View of AnnData object with n_obs × n_vars = 2 × 2




添加元数据

  • 给观察(Observation)或变量(Variable)同一级别添加元数据,adata.obsadata.var 都是 Pandas DataFrames
  • pandas.Categorical():表示经典 R / S-plus 方式的分类变量,可以降低数据存储提升计算速度
  • 使用元数据构造子集
import numpy as np
import pandas as pd
import anndata as ad
from scipy.sparse import csr_matrix

counts = csr_matrix(np.random.poisson(1, size=(100, 2000)), dtype=np.float32)
adata = ad.AnnData(counts)

ct = np.random.choice(['B', 'T', 'Monocyte'], size=(adata.n_obs,))  # 随机生成cell_type
adata.obs['cell_type'] = pd.Categorical(ct)  # 为了效率,用pd.Categorical()
print(adata.obs)
#    cell_type
# 0          B
# 1   Monocyte
# 2          T
# ......
# [100 rows x 1 columns]

print(adata)
# AnnData object with n_obs × n_vars = 100 × 2000
#     obs: 'cell_type'




观察或变量的元数据

  • 可在任何级别上有元数据,如 UMAP 嵌入数据
  • obsmvarm 添加元数据
  • 使用正态分布随机生成一个矩阵作为 UMAP 嵌入数据
  • 元数据可以为 Pandas DataFrames、Scipy 稀疏矩阵、NumPy Array
  • 使用 Scanpy 的话,Columns 不容易绘制,而 .obs 容易绘制
import numpy as np
import pandas as pd
import anndata as ad
from scipy.sparse import csr_matrix

counts = csr_matrix(np.random.poisson(1, size=(100, 2000)), dtype=np.float32)
adata = ad.AnnData(counts)

ct = np.random.choice(['B', 'T', 'Monocyte'], size=(adata.n_obs,))  # 随机生成cell_type
adata.obs['cell_type'] = pd.Categorical(ct)  # 为了效率,用pd.Categorical()
adata.obsm['X_umap'] = np.random.normal(0, 1, size=(adata.n_obs, 2))
adata.varm['gene_stuff'] = np.random.normal(0, 1, size=(adata.n_vars, 5))

print(adata.obsm)
# AxisArrays with keys: X_umap
print(adata)
# AnnData object with n_obs × n_vars = 100 × 2000
#     obs: 'cell_type'
#     obsm: 'X_umap'
#     varm: 'gene_stuff'




非结构化元数据

  • .uns 可存储非结构化元数据,可以是任意数据。
import numpy as np
import anndata as ad
from scipy.sparse import csr_matrix

counts = csr_matrix(np.random.poisson(1, size=(100, 2000)), dtype=np.float32)
adata = ad.AnnData(counts)
adata.uns['random'] = [1, 2, 3]
print(adata.uns)
# OverloadedDict, wrapping:
# 	OrderedDict([('random', [1, 2, 3])])
# With overloaded keys:
# 	['neighbors'].




  • 可能有不同形式的原始核心数据,如一个标准化一个非标准化,都可以存储在不同层中。
import numpy as np
import anndata as ad
from scipy.sparse import csr_matrix

counts = csr_matrix(np.random.poisson(1, size=(100, 2000)), dtype=np.float32)
adata = ad.AnnData(counts)
adata.layers['log_transformed'] = np.log1p(adata.X)
print(adata)
# AnnData object with n_obs × n_vars = 100 × 2000
#     layers: 'log_transformed'




转换为DataFrame

  • 可以将其中一个层转换为 DataFrame
import numpy as np
import anndata as ad
from scipy.sparse import csr_matrix

counts = csr_matrix(np.random.poisson(1, size=(100, 2000)), dtype=np.float32)
adata = ad.AnnData(counts)

adata.obs_names = [f'Cell_{i:d}' for i in range(adata.n_obs)]
adata.var_names = [f'Gene_{i:d}' for i in range(adata.n_vars)]
adata.layers['log_transformed'] = np.log1p(adata.X)

print(adata.to_df(layer='log_transformed'))  # 可以看到保留了索引




保存结果

  • AnnData 对应文件格式为 h5ad
  • 如果包含少量类别的字符串列还不是类别,自动转换为类别。
  • 该“类别”指 CategoricalDtype ,可以降低数据存储提升计算速度
import numpy as np
import pandas as pd
import anndata as ad
from scipy.sparse import csr_matrix

counts = csr_matrix(np.random.poisson(1, size=(100, 2000)), dtype=np.float32)
adata = ad.AnnData(counts)

adata.obs_names = [f'Cell_{i:d}' for i in range(adata.n_obs)]
adata.var_names = [f'Gene_{i:d}' for i in range(adata.n_vars)]

ct = np.random.choice(['B', 'T', 'Monocyte'], size=(adata.n_obs,))
adata.obs['cell_type'] = pd.Categorical(ct)
adata.obsm['X_umap'] = np.random.normal(0, 1, size=(adata.n_obs, 2))
adata.varm['gene_stuff'] = np.random.normal(0, 1, size=(adata.n_vars, 5))
adata.uns['random'] = [1, 2, 3]
adata.layers['log_transformed'] = np.log1p(adata.X)
adata.write('my_results.h5ad', compression='gzip')

在 Linux 下执行命令:h5ls my_results.h5ad

X                        Group
layers                   Group
obs                      Group
obsm                     Group
obsp                     Group
uns                      Group
var                      Group
varm                     Group
varp                     Group




视图和副本

  • 假设观测数据来自一项多年的研究,记录了 10 个读数,样本取自不同地点的不同受试者。
  • 类似于 NumPy Array,AnnData 对象既可以存储真实数据,也可以存储另一个 AnnData 对象的引用。
  • 子集 AnnData 对象总是返回视图,有两个优点——不需要分配新内存、可以修改底层的 AnnData 对象
  • 可以通过 .copy() 获取真实 AnnData 对象。但这样做没什么必要,因为调用 .[] 都会在内部调用 .copy()
  • AnnData 的 [],整型索引类似 pandas 的 .iloc,字符串索引类似 .loc
  • 如果访问 AnnData 视图的某些部分,内容会被自动复制,并生成一个数据存储对象
  • 可以用所有同 pandas 的切片操作,如序列或布尔索引
import numpy as np
import pandas as pd
import anndata as ad
from scipy.sparse import csr_matrix

counts = csr_matrix(np.random.poisson(1, size=(100, 2000)), dtype=np.float32)
adata = ad.AnnData(counts)
adata.obs_names = [f'Cell_{i:d}' for i in range(adata.n_obs)]
adata.var_names = [f'Gene_{i:d}' for i in range(adata.n_vars)]

obs_meta = pd.DataFrame({
    'time_yr': np.random.choice([0, 2, 4, 8], adata.n_obs),
    'subject_id': np.random.choice(['subject 1', 'subject 2', 'subject 4', 'subject 8'], adata.n_obs),
    'instrument_type': np.random.choice(['type a', 'type b'], adata.n_obs),
    'site': np.random.choice(['site x', 'site y'], adata.n_obs),
},
    index=adata.obs.index,  # 同观测的索引
)
adata = ad.AnnData(adata.X, obs=obs_meta, var=adata.var)  # 构建新的AnnData
print(adata)
# AnnData object with n_obs × n_vars = 100 × 2000
#     obs: 'time_yr', 'subject_id', 'instrument_type', 'site'

print(adata[:5, ['Gene_1', 'Gene_3']])  # 生成的是视图
# View of AnnData object with n_obs × n_vars = 5 × 2
#     obs: 'time_yr', 'subject_id', 'instrument_type', 'site'

adata_subset = adata[:5, ['Gene_1', 'Gene_3']].copy()  # 全新AnnData

print(adata[:3, 'Gene_1'].X.toarray().tolist())
adata[:3, 'Gene_1'].X = [0, 0, 0]  # 视图也可以设值
print(adata[:3, 'Gene_1'].X.toarray().tolist())
# [[0.0], [0.0], [0.0]]

adata_subset = adata[:3, ['Gene_1', 'Gene_2']]  # 访问视图的某些部分,内容会被自动复制,并生成一个数据存储对象
print(adata_subset)
# View of AnnData object with n_obs × n_vars = 3 × 2
#     obs: 'time_yr', 'subject_id', 'instrument_type', 'site'

adata_subset.obs['foo'] = range(3)  # 现在adata_subset不再是adata的引用
print(adata_subset)
# AnnData object with n_obs × n_vars = 3 × 2
#     obs: 'time_yr', 'subject_id', 'instrument_type', 'site', 'foo'

print(adata[adata.obs.time_yr.isin([2, 4])].obs.head())




部分读取

如果 h5ad 文件非常大,可以使用 backed 模式部分读入内存

import anndata as ad

adata = ad.read('my_results.h5ad', backed='r')
print(adata.isbacked)
# True

print(adata.filename)
# my_results.h5ad

adata.file.close()




pytorch模型与anndata接口




惰性连接多个AnnData对象




连接pytorch模型和AnnData对象




命令



h5ls

功能:以指定格式打印数据集信息。

用法:h5ls [OPTIONS] file [OBJECTS...]

参数

简写全写功能
-a–address打印原始数据地址,必须和 -v 或 --verbose 一起使用
-d–data打印数据集的值
–enable-error-stack打印错误栈
–follow-symlinks使用符号链接显示目标对象信息
–no-dangling-links检查不解析为现有对象的符号链接,必须和 --follow-symlinks 一起使用
-f–full打印完整路径名称
-g–group显示组的信息
-l–label标记复合数据集的成员
-r–recursive递归列出所有组
-s–string以 ASCII 格式打印 1 字节数据集
-S–simple使用机器可读的输出格式
-wN–width=N设置输出的列数
-v–verbose生成更多信息
-V–version打印版本号
–vfd=DRIVER指定虚拟文件驱动
-x–hexdump以十六进制格式显示原始数据
OBJECTS每个对象由一个HDF5文件名(可选地,后面跟着一个斜杠)和文件中的一个对象名称组成(如果文件中没有指定对象,则显示根组的内容)。

常用命令

h5ls x.h5ad  # 查看基础信息

h5ls -d x.h5ad/obs/louvain  # 查看/obs/louvain的数据
h5ls -d x.h5ad/obs/__categories/louvain  # 查看/obs/louvain的数据

h5ls -d -S x.h5ad/obs/louvain | sort | uniq  # 对/obs/louvain的数据去重
h5ls -d -S x.h5ad/obs/louvain | sort | uniq -c  # 对/obs/louvain的数据去重并显示出现次数



h5dump

功能:显示 HDF5 内容。

用法:h5dump [OPTIONS] file

参数

简写全写功能
-h–help帮助文档
-B–bootblockPrint the content of the boot block. (This option is not yet implemented.)
-H–header标题
-A属性头和属性值
-i–object-ids对象ids(貌似是全部打印)
-r–stringPrint 1-bytes integer datasets as ASCII.
-V–version版本号
-a P–attribute=P指定属性
-d P–dataset=P指定数据集
-f D–filedriver=DSpecify which driver to open the file with.
-g P–group=P指定组
-l P–soft-link=PPrint the value(s) of the specified soft link.
-o F–output=FOutput raw data into file F.
-t T–datatype=TPrint the specified named datatype.
-w N–width=N输出的列数
-x–xmlOutput XML using XML schema (default) instead of DDL.
-u–use-dtdOutput XML using XML DTD instead of DDL.
-D U–xml-dtd=UIn XML output, refer to the DTD or schema at U instead of the default schema/DTD.
-X S–xml-dns=SIn XML output, (XML Schema) use qualified names in the XML: “:”: no namespace, default: “hdf5:”
-s L–start=L子集选择开始的偏移量
-S L–stride=LHyperslab stride. Default: 1 in all dimensions.
-c L–count=L块的数量
-k L–block=LSize of block in hyperslab. Default: 1 in all dimensions.
Indicate that all following arguments are non-options. E.g., to dump a file called `-f’, use h5dump – -f.
fileThe file to be examined.

常用命令

h5dump -H x.h5ad  # 打印标题

h5dump -g obs x.h5ad  # 打印Group为obs的数据
h5dump -g /obs/__categories x.h5ad  # 打印Group为obs的数据

h5dump -d X -c "10,10" x.h5ad  # 打印Dataset为X的(10, 10)数据

h5dump -d /obs/louvain x.h5ad  # 打印/obs/louvain的数据
h5dump -d /obs/louvain -c 100 x.h5ad  # 打印/obs/louvain的数据

h5dump -a /obs/_index x.h5ad  # 打印属性



h5diff

功能:比较



h5debug



h5check




h5ad可视化工具

HDFView




AnnData数据结构

  • obs:观察值,如细胞
  • var:变量,特征,如基因
  • X:矩阵,如某基因在细胞里的表达量,X[0] 是第一个细胞的所有基因的表达量,X[:, 0] 是第一个基因在左右细胞的表达量




参考文献

  1. anndata Documentation
  2. UMAP Documentation
  3. Scanpy Documentation
  4. Pandas数据分析从入门到实战
  5. Scanpy(一)AnnData数据结构与一些API用法介绍
  6. HDF5 小试——高大上的多对象文件格式
  7. h5dump: Displays HDF5 file contents
  8. _h5ls GitHub
  9. Linux uniq 命令
  • 11
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Pandas是一个Python库,用于数据处理和分析。在数据分析中,预处理是非常重要的一步,因为它可以帮助我们清洗和转换数据,使其更适合进行分析Pandas提供了一些强大的预处理功能,包括数据清洗、数据转换、数据重塑和数据合并等。在使用Pandas进行数据分析时,预处理是必不可少的一步。 ### 回答2: 在数据分析中,数据的预处理是一个必要的过程。它的主要目的是清洗数据,准备数据,以便后续分析。在Python中,pandas是一种广泛使用的数据处理库。pandas可以通过其高效的数据结构和操作方法来清洗和处理数据。在本文中,将介绍pandas预处理的一些常见技术。 一、读取数据 在pandas中,使用read_csv()函数读取CSV格式的数据文件,read_excel()函数读取Excel格式的数据文件。它们都有很多选项,可以根据具体文件的格式进行设置。 二、查看数据 在pandas中,使用以下函数来查看数据: 1. head() - 显示数据框的前几行; 2. tail() - 显示数据框的后几行; 3. columns - 显示数据框的列名; 4. shape - 显示数据框的行列数; 5. info() - 显示数据框的基本信息,包括每列的名称、非空值数量和数据类型。 三、数据清洗 在数据清洗中,有以下一些常见的技术: 1. 删除重复行:使用drop_duplicates()函数; 2. 替换空值:使用fillna()函数; 3. 删除空值:使用dropna()函数; 4. 更改数据类型:使用astype()函数。 四、数据准备 在数据准备中,有以下一些常见的技术: 1. 数据合并:使用merge()函数; 2. 数据筛选:使用loc()函数或者iloc()函数; 3. 数据分组:使用groupby()函数; 4. 数据排序:使用sort_values()函数。 五、数据分析 在数据分析中,有以下一些常见的技术: 1. 数据聚合:使用agg()函数; 2. 统计描述:使用describe()函数; 3. 数据可视化:使用matplotlib或者seaborn库。 综上所述,pandas预处理是数据分析中必不可少的一步。通过使用pandas提供的函数和方法,可以方便地清理和处理数据,使其更容易被分析。 ### 回答3: PandasPython中最强大的数据处理库之一,它提供了DataFrame和Series这两种数据结构,可以快速便捷地处理数据。在数据分析过程中,我们往往需要先对数据进行预处理,以便后续的分析Pandas提供了一系列的方法和函数,可以帮助我们进行数据的预处理。 首先,在进行数据分析之前,我们需要了解自己所面对的数据类型和数据结构Pandas中的DataFrame结构就是类似于表格的结构,每一行代表一个样本,每一列代表一个属性。Series则是一维的数组结构。通过pandas.read_csv(),我们可以读取CSV格式的数据,并转化为DataFrame结构。 接下来,我们要对数据进行一些基本的处理,例如数据清洗、数据去重、缺失值处理、异常值处理等。在数据清洗过程中,我们往往需要对数据进行一些特殊的处理,例如字符串的分割、合并、替换等操作,Pandas提供了一系列能够对文本进行操作的函数。在数据去重方面,我们可以使用drop_duplicates()函数,它可以去除DataFrame中的重复记录。在处理缺失值时,Pandas提供了一系列的函数,如fillna()函数、dropna()函数,可以方便地将NaN值变为其他有意义的值,或者删除缺失值的行或列。在异常值处理方面,我们可以使用isoutlier()函数来找到数据中的异常值,并进行处理。 在数据预处理完成后,我们可以对数据进行一些统计分析,例如计算小计、计算总计、分位数、极差、方差、标准差等统计指标。我们可以使用describe()函数来获得数据的统计描述,还可以使用groupby()函数来对数据分组,使用agg()函数对每组进行计算统计指标。此外,我们还可以对数据进行排序、丢弃、合并等操作。 总之,Pandas是一个非常强大的Python库,可以轻松处理数据预处理和数据处理方面的任务。Pandas作为数据分析和数据处理的基础库,使用熟练后可以在数据分析中发挥更大的作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XerCis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值