簡體   English   中英

熊貓groupby按條件計數

[英]Pandas groupby count with conditions

示例數據

給定以下數據框:

| feature | gene  |  target  | pos | 
| 1_1_1   | NRAS  |  AATTGG  | 60  |
| 1_1_1   | NRAS  |  TTGGCC  | 6   |
| 1_1_1   | NRAS  |  AATTGG  | 20  |
| 1_1_1   | KRAS  |  GGGGTT  |  0  |
| 1_1_1   | KRAS  |  GGGGTT  |  0  |
| 1_1_1   | KRAS  |  GGGGTT  |  0  |
| 1_1_2   | NRAS  |  CCTTAA  | 2   |
| 1_1_2   | NRAS  |  GGAATT  | 8   |
| 1_1_2   | NRAS  |  AATTGG  | 60  |

問題

對於每個功能,我想按照以下規則計算每個基因中出現多少個靶標:

  • 如果每個基因的靶標僅出現在一個位置(pos列),則每次看到的靶標計數為1
  • 如果同一靶標出現在每個基因的多個位置,則其計數為(在找到的位置/總位置中的計數)
  • 總結每個特征的每個基因的總數

到目前為止我做了什么

matches.groupby(["FeatureID", "gene"]).size().reset_index()

matches['multi_mapped'] = np.where(matches.groupby(["FeatureID", "gene", "target"]).pos.transform('nunique') > 1, "T", '')

這給了我一個數據框,其中出現在多個位置的目標被標記為true。 現在,我只需要弄清楚如何將計數標准化。

所需的輸出

| feature | gene  |  count
| 1_1_1   | NRAS  |   2
| 1_1_1   | KRAS  |   1
| 1_1_2   | NRAS  |   3

因此,在上面的示例中,對於1_1_1 NRAS,在位置60和位置20都找到了AATTGG,它們的計數均為0.5。 由於TTGGCC在一個位置被發現一次,因此其計數為1。這使總數為2。

如果對於1_1_1 NRAS TTGGCC在同一位置被發現3次,則每一個都將計數為1,總共3 + .5 + .5 = 4。

解決方案需要檢查出現在不同位置的相同目標,然后相應地調整計數,這就是我遇到困難的部分。 我的最終目標是選擇每組中計數最高的基因。

對我來說還不是很清楚,為什么第一行的計數應該為2。您能嘗試解決這個問題嗎:

import pandas as pd
feature = ["1_1_1"]*6 +["1_1_2"]*3
gene = ["NRAS"]*3+["KRAS"]*3+["NRAS"]*3
target = ["AATTGG","TTGGCC", "AATTGG"]+ ["GGGGTT"]*3 + ["CCTTAA", "GGGGTT", "AATTGG"]
pos = [60,6,20,0,0,0,2,8,60]
df = pd.DataFrame({"feature":feature,
                   "gene":gene,
                   "target":target,
                   "pos":pos})

df.groupby(["feature", "gene"])\
  .apply(lambda x:len(x.drop_duplicates(["target", "pos"])))

好吧,我知道了。 如果有更有效的方法來做到這一點,我全神貫注!

    # flag targets that are multi-mapped and add flag as new column
    matches['multi_mapped'] = np.where(matches.groupby(["FeatureID", "gene", "target"]).pos.transform('nunique') > 1, "T", '')

    # separate multi and non multi mapped reads using flag
    non = matches[matches["multi_mapped"] != "T"]\
        .drop("multi_mapped", axis=1)
    multi = matches[matches["multi_mapped"] == "T"]\
        .drop("multi_mapped", axis=1)

    # add counts to non multi mapped reads
    non = non.groupby(["FeatureID", "gene", "target"])\
        .count().reset_index().rename(columns={"pos":"count"})

    # add counts to multi-mapped reads with normaliztion 
    multi["count"] = multi.groupby(["FeatureID", "gene", "target"])\
          .transform(lambda x: 1/x.count())
    multi.drop("pos", axis=1, inplace=True)

    # join the multi and non back together
    counts = pd.concat([multi, non], axis=0)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM