错误情况:出现Nan
根据https://github.com/scverse/scanpy/issues/653 里面的讨论,我对我的数据进行了核查,发现有adata.X里面有负值
检查了一下,原始数据里面是没有负值的,说明是在标准化处理时除了错误
因此利用adata.X=adata.layers['raw_count']
重新进行标准化处理。经过sc.pp.normalize_total(adata, target_sum=1e6)
和sc.pp.log1p(adata)
之后,重新检查adata.X,一切正常,没有负值
说明是在scale那一步出了问题.
以下是GPT的解释
scanpy.pp.scale 的主要作用是对每个基因的表达数据进行标准化处理,也就是常说的 z-score 标准化。下面详细说明其原理和为什么会产生负值:
标准化原理
均值中心化:对于数据矩阵中每个基因(通常对应矩阵的每一列),函数首先计算所有细胞中该基因的平均表达值。然后,从每个细胞的表达值中减去这个平均值,使得该基因在标准化后的数据中均值为 0。
方差缩放:接下来,函数计算该基因表达的标准差,并将中心化后的每个值除以标准差,使得该基因的表达数据具有单位方差。
这种处理使得不同基因的数据能够在同一尺度上比较,避免由于原始表达量级差异过大而影响后续分析。
为什么会生成负值
中心化的必然结果:在中心化过程中,任何低于均值的表达值在减去均值后都会变为负数。这是标准化过程中的正常现象。例如,如果一个基因在某个细胞中的表达低于整体均值,那么计算后的 z-score 就会是负值。
数据分布:原始数据经过 log 转换或归一化后,通常是非负的,但在做中心化后,低表达的部分就自然会落在 0 以下,从而出现负值。
与 log fold change 的关系
在 sc.tl.rank_genes_groups 进行差异基因分析时,算法可能会尝试计算某种形式的 fold change。如果使用的是经过标准化(即中心化和缩放后的)数据,那么因为数据中存在负值,直接进行对数转换就会遇到数学上的问题(对数函数无法处理负数),从而产生 NaN 值。
而在https://mp.weixin.qq.com/s/YGsHqjpmHbWnmmub2w-OqQ 在这里面可以看到scale有助于后续的降维聚类。
因此,我们应该在scale前,让adata.raw=adata
,然后在后面sc.tl.rank_genes_groupss
时,use_raw=True
,从而解决这个问题: