将没有覆盖的垃圾箱填充为 0

问题描述 投票:0回答:1

我需要生成一个热图,其中包含确定数量的箱内位置的平均覆盖范围,无论每个箱内转录组中的碱基数量如何。换句话说,如果我想要有 10 个 bin,对于一个转录组,它可能有 1000 个碱基分布在 10 个 bin 中,而另一个转录组可能有 2445 个碱基分布在 10 个 bin 中。

问题是在我的覆盖文件中,有一些空白不属于任何垃圾箱。例如,如果我想要 5 个垃圾箱超过 10 个位置,我将有:(0,2]、(2,4]、(4,6]、(6,8]、(8,10])。如果我的位置覆盖范围为 1, 5, 5, 5, 7, 7, 10,垃圾箱“(2,4]”将被隐藏,因此不会出现在热图中。我想要的是这些没有覆盖范围的垃圾箱被填充0,以便它们出现在热图中。

我正在将 python 与 pandas、seaborn 和 matplot.pyplot 库一起使用

在下图中,第一行是我的垃圾箱的边缘位置,数据框是垃圾箱的覆盖范围: enter image description here

输入示例:

chr17   1   1
chr17   5   1
chr17   5   2
chr17   5   2
chr17   7   1
chr17   7   5
chr17   10  1

问题:

    chr                data_bin        avg
  chr17                   (0,2]          1
  chr17                   (4,6]       1.66
  chr17                   (4,6]       1.66
  chr17                   (4,6]       1.66
  chr17                   (6,8]          3
  chr17                   (6,8]          3
  chr17                  (8,10]          1

预期:

    chr                data_bin        avg
  chr17                   (0,2]          1
  **chr17                   (2,4]          0**
  chr17                   (4,6]       1.66
  chr17                   (4,6]       1.66
  chr17                   (4,6]       1.66
  chr17                   (6,8]          3
  chr17                   (6,8]          3
  chr17                  (8,10]          1

我使用的功能是:

def bins_calculator(path_txt:str, start:int,end:int):
    column_names =["chr", "pos", "cov"]
    data = pd.read_csv(path_txt, names = column_names, sep = '\t')
    step = int((end - start) / 10)
    n_bins = [start + i * step for i in range(11)]
    n_bins[-1] = end
    data["data_bin"] = pd.cut(data["pos"], bins = n_bins)
    data["avg"] = data.groupby("data_bin", observed = False)["cov"].transform("mean")
    filtered_data = data[["chr","data_bin","avg"]].drop_duplicates("data_bin")
    return filtered_data

对此问题有任何疑问,请在评论中告诉我:)

python pandas bin
1个回答
0
投票

IIUC 您可以使用

.merge
合并缺失的类别,然后用您想要的值填充任意
NaNs

df["data_bin"] = pd.cut(df["pos"], range(0, 12, 2))

df = pd.merge(
    df,
    df["data_bin"].cat.categories.to_frame(),
    left_on="data_bin",
    right_on=0,
    how="outer",
)[["chr", "data_bin", "cov"]]

df["chr"] = df["chr"].ffill().bfill()
df["cov"] = df["cov"].fillna(0)

df["avg"] = df.groupby("data_bin")["cov"].transform("mean")
print(df)

打印:

     chr     data_bin  cov       avg
0  chr17   (0.0, 2.0]  1.0  1.000000
1  chr17   (2.0, 4.0]  0.0  0.000000
2  chr17   (4.0, 6.0]  1.0  1.666667
3  chr17   (4.0, 6.0]  2.0  1.666667
4  chr17   (4.0, 6.0]  2.0  1.666667
5  chr17   (6.0, 8.0]  1.0  3.000000
6  chr17   (6.0, 8.0]  5.0  3.000000
7  chr17  (8.0, 10.0]  1.0  1.000000
© www.soinside.com 2019 - 2024. All rights reserved.