# Getting normalized expression

**URL:** https://discourse.scverse.org/t/getting-normalized-expression/3976
**Category:** scvi-tools
**Tags:** integration, diff-exp, scvi
**Created:** [May 6, 2026, 3:20pm UTC](https://discourse.scverse.org/t/getting-normalized-expression/3976 "2026-05-06T15:20:34Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![Kray](https://avatars.discourse-cdn.com/v4/letter/k/5f8ce5/32.png) [@Kray](https://discourse.scverse.org/u/Kray)
#### Post date: [May 6, 2026, 3:20pm UTC](https://discourse.scverse.org/t/getting-normalized-expression/3976/1 "2026-05-06T15:20:34Z")

</div>

Hi,

I am working on a big sized scRNAseq atlas with 2 million cells. I want to get the normalized expression. However, since it returns a data frame/numpy array, I run out of memory every time I am trying to retrieve the normalized expressions. I need it for performing DE. Is there any other way to get it? or perform DE between clusters without using it?

Thanks,  
Kam

---

<div class="post-metadata">

### Author: ![ori-kron-wis](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/ori-kron-wis/32/1099_2.png) [@ori-kron-wis](https://discourse.scverse.org/u/ori-kron-wis)
#### Post date: [May 7, 2026, 8:41am UTC](https://discourse.scverse.org/t/getting-normalized-expression/3976/2 "2026-05-07T08:41:46Z")

</div>

Yes, of course, there’s a direct way to run DE from a scVI-trained model, without the need to get\_normalization\_expression first: `model.differential_expression(…),` and you can state if you want to do group vs group, group vs all , by which groups, and so on..

If you still need the whole normalized expression itself, and do not have enough memory, you can extract it in smaller chunks of adatas.

---

<div class="post-metadata">

### Author: ![Kray](https://avatars.discourse-cdn.com/v4/letter/k/5f8ce5/32.png) [@Kray](https://discourse.scverse.org/u/Kray)
#### Post date: [May 7, 2026, 8:55am UTC](https://discourse.scverse.org/t/getting-normalized-expression/3976/3 "2026-05-07T08:55:37Z")

</div>

Hi,

Thanks for your response. I tried the direct way using model.differential\_expression. It throws an out of memory error due to the size of the adata probably. Is there a way to resolve this? or may be extracting the normalized data in smaller chunks might be useful, could you please guide me on how to do it?

---

<div class="post-metadata">

### Author: ![ori-kron-wis](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/ori-kron-wis/32/1099_2.png) [@ori-kron-wis](https://discourse.scverse.org/u/ori-kron-wis)
#### Post date: [May 7, 2026, 9:11am UTC](https://discourse.scverse.org/t/getting-normalized-expression/3976/4 "2026-05-07T09:11:41Z")

</div>

should be something like:

```auto
import numpy as np
import scipy.sparse as sp

chunk_size = 50000
all_chunks = []

for start in range(0, adata.n_obs, chunk_size):
    end = min(start + chunk_size, adata.n_obs)

    x = model.get_normalized_expression(
        adata=adata[start:end],
        return_numpy=True,
    )

    all_chunks.append(sp.csr_matrix(x))

```

which will store it in a sparse matrix.

Do you really need to run DE on all cells? usually we run group vs all/group, e.g:

```auto
de_df = model.differential_expression(
    groupby="cell_type",
    group1="B_cell",
    group2="T_cell",
)

```

---

<div class="post-metadata">

### Author: ![Kray](https://avatars.discourse-cdn.com/v4/letter/k/5f8ce5/32.png) [@Kray](https://discourse.scverse.org/u/Kray)
#### Post date: [May 7, 2026, 9:42am UTC](https://discourse.scverse.org/t/getting-normalized-expression/3976/5 "2026-05-07T09:42:51Z")

</div>

Thanks a lot!  
I am looking for cell specific markers so I have generated clusters and performing DE between each cluster vs other clusters.

---

<div class="post-metadata">

### Author: ![Kray](https://avatars.discourse-cdn.com/v4/letter/k/5f8ce5/32.png) [@Kray](https://discourse.scverse.org/u/Kray)
#### Post date: [May 7, 2026, 9:55am UTC](https://discourse.scverse.org/t/getting-normalized-expression/3976/6 "2026-05-07T09:55:35Z")

</div>

Can I store the normalized expression as a sparse matrix in h5ad object for future use?

---

<div class="post-metadata">

### Author: ![ori-kron-wis](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/ori-kron-wis/32/1099_2.png) [@ori-kron-wis](https://discourse.scverse.org/u/ori-kron-wis)
#### Post date: [May 7, 2026, 10:07am UTC](https://discourse.scverse.org/t/getting-normalized-expression/3976/7 "2026-05-07T10:07:02Z")

</div>

Yes, that’s the idea.

For the clusters, then just replace groupby to the “cluster\_column” and group 1 and 2 to the clusters ids

---

<div class="post-metadata">

### Author: ![cane11](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/cane11/32/241_2.png) [@cane11](https://discourse.scverse.org/u/cane11)
#### Post date: [May 7, 2026, 12:35pm UTC](https://discourse.scverse.org/t/getting-normalized-expression/3976/8 "2026-05-07T12:35:35Z")

</div>

You will want to add a filter to set counts to zero below a certain threshold like 1e-5 to increase sparsity. However, we usually do not recommend using normalized counts for downstream tasks such as Wilcoxon or t-test.

---

<div class="post-metadata">

### Author: ![Kray](https://avatars.discourse-cdn.com/v4/letter/k/5f8ce5/32.png) [@Kray](https://discourse.scverse.org/u/Kray)
#### Post date: [May 7, 2026, 1:11pm UTC](https://discourse.scverse.org/t/getting-normalized-expression/3976/9 "2026-05-07T13:11:21Z")

</div>

Is there an option to do that when getting the normalized expression?

---

<div class="post-metadata">

### Author: ![ori-kron-wis](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/ori-kron-wis/32/1099_2.png) [@ori-kron-wis](https://discourse.scverse.org/u/ori-kron-wis)
#### Post date: [May 7, 2026, 1:25pm UTC](https://discourse.scverse.org/t/getting-normalized-expression/3976/10 "2026-05-07T13:25:57Z")

</div>

you need to do that on raw data, as preprocessing with scanpy/anndata, before training the model

---

<div class="post-metadata">

### Author: ![cane11](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/cane11/32/241_2.png) [@cane11](https://discourse.scverse.org/u/cane11)
#### Post date: [May 12, 2026, 5:45am UTC](https://discourse.scverse.org/t/getting-normalized-expression/3976/11 "2026-05-12T05:45:06Z")

</div>

> [@ori-kron-wis](#):
>
> ```auto
> x = model.get_normalized_expression(
> adata=adata[start:end],
> return_numpy=True,
> )
> 
> ```

I meant at this step for x you can set a filter and set counts to zero below this threshold.

---

<div class="post-metadata">

### Author: ![cane11](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/cane11/32/241_2.png) [@cane11](https://discourse.scverse.org/u/cane11)
#### Post date: [May 12, 2026, 5:46am UTC](https://discourse.scverse.org/t/getting-normalized-expression/3976/12 "2026-05-12T05:46:28Z")

</div>

It might be also worth to compute posterior predictive samples - those are the counts sampled from the negative binomial distribution using the learned parameters from scVI.

---

<div class="post-metadata">

### Author: ![Kray](https://avatars.discourse-cdn.com/v4/letter/k/5f8ce5/32.png) [@Kray](https://discourse.scverse.org/u/Kray)
#### Post date: [May 12, 2026, 8:21am UTC](https://discourse.scverse.org/t/getting-normalized-expression/3976/13 "2026-05-12T08:21:11Z")

</div>

Thanks a lot! Could you please tell me the use of computing the posterior predictive samples? I am new to this topic and learning about it.

---

<div class="post-metadata">

### Author: ![cane11](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/cane11/32/241_2.png) [@cane11](https://discourse.scverse.org/u/cane11)
#### Post date: [May 13, 2026, 9:54am UTC](https://discourse.scverse.org/t/getting-normalized-expression/3976/14 "2026-05-13T09:54:49Z")

</div>

[scvi.model.SCVI — scvi-tools](https://docs.scvi-tools.org/en/latest/api/reference/scvi.model.SCVI.html#scvi.model.SCVI.posterior_predictive_sample) and we described the use of it in the scvi-hub manuscripthttps://www.nature.com/articles/s41592-025-02799-9.
