【问题标题】:How to slice/chop a string using multiple indexes in a panda DataFrame如何在 panda DataFrame 中使用多个索引对字符串进行切片/切碎
【发布时间】:2021-03-02 21:53:54
【问题描述】:

我需要一些关于以下问题的建议: 我有一个如下所示的 DataFrame:

   ID                   SEQ LEN BEG_GAP END_GAP  
0  A1        AABBCCDDEEFFGG  14       2       4  
1  A1        AABBCCDDEEFFGG  14      10      12
2  B1        YYUUUUAAAAMMNN  14       4       6
3  B1        YYUUUUAAAAMMNN  14       8      12
4  C1  LLKKHHUUTTYYYYYYYYAA  20       7       9
5  C1  LLKKHHUUTTYYYYYYYYAA  20      12      15
6  C1  LLKKHHUUTTYYYYYYYYAA  20      17      18

我需要得到的是SEQ,它在不同的BEG_GAPEND_GAP 之间分开。对于只有一对间隙的序列,我已经解决了(感谢之前的问题),但在这里它们有多个。

序列应该是这样的:

  ID                   SEQ 
0 A1       AA---CDDEE---GG  
1 B1       YYUU---A-----NN  
2 C1  LLKKHHU---YY----Y--A  

或者在分解的 DF 中:

  ID Seq_slice
0 A1        AA
1 A1     CDDEE  
2 A1        GG
3 B1      YYUU
4 B1         A   
5 B1        NN
6 C1   LLKKHHU
7 C1        YY
8 C1         Y
9 C1         A

目前,我正在使用一段代码(感谢之前的问题),该代码仅在存在一个差距时才有效,它看起来像这样:

import pandas as pd

df = pd.read_csv("..\path_to_the_csv.csv")


df["BEG_GAP"] = df["BEG_GAP"].astype(int)
df["END_GAP"]= df["END_GAP"].astype(int)

df['SEQ'] = df.apply(lambda x: [x.SEQ[:x.BEG_GAP], x.SEQ[x.END_GAP+1:]], axis=1)

output = df.explode('SEQ').query('SEQ!=""')

但这有一个问题,它会生成一堆实际上并不存在的序列,因为它们实际上中间还有另一个间隙。 即它会产生什么:

  ID   Seq_slice
0 A1          AA
1 A1    CDDEEFFG #<- this one shouldn't exist! Because there's another gap in 10-12
2 A1  AABBCCDDEE #<- Also, this one shouldn't exist, it's missing the previous gap.
3 A1          GG

以此类推,还有其他序列。如您所见,有些切片没有生成,有些切片是错误的,因为我不知道如何告诉代码在分析序列时记住所有间隙。

感谢所有建议,希望我清楚!

【问题讨论】:

    标签: python python-3.x pandas string dataframe


    【解决方案1】:

    让我们尝试定义一个函数和apply

    def truncate(data):
        seq = data.SEQ.iloc[0]
        ll = data.LEN.iloc[0]
        return [seq[x:y] for x,y in zip([0]+list(data.END_GAP),
                                        list(data.BEG_GAP)+[ll])]
    
    (df.groupby('ID').apply(truncate)
       .explode().reset_index(name='Seq_slice')
    )
    

    输出:

       ID Seq_slice
    0  A1        AA
    1  A1    CCDDEE
    2  A1        GG
    3  B1      YYUU
    4  B1        AA
    5  B1        NN
    6  C1   LLKKHHU
    7  C1       TYY
    8  C1        YY
    9  C1        AA
    

    【讨论】:

      【解决方案2】:

      一行:

      df.groupby('ID').agg({'BEG_GAP': list, 'END_GAP': list, 'SEQ': max, 'LEN': max}).apply(lambda x: [x['SEQ'][b: e] for b, e in zip([0] + x['END_GAP'], x['BEG_GAP'] + [x['LEN']])], axis=1).explode()
      
      ID
      A1         AA
      A1     CCDDEE
      A1         GG
      B1       YYUU
      B1         AA
      B1         NN
      C1    LLKKHHU
      C1        TYY
      C1         YY
      C1         AA
      

      【讨论】:

        猜你喜欢
        • 2021-11-20
        • 1970-01-01
        • 2021-03-12
        • 2017-11-20
        • 1970-01-01
        • 1970-01-01
        • 2012-11-20
        • 2011-12-03
        • 1970-01-01
        相关资源
        最近更新 更多