【问题标题】:The best way to group rows with same names对具有相同名称的行进行分组的最佳方法
【发布时间】:2020-11-29 19:07:00
【问题描述】:

我有那个df:

gene  person  allele    allele2
A1      p1       G          C
A2      p1       A          C
A3      p1       A          T
A1      p2       G          C
A2      p2       T          T
A3      p2       G          C
A4      p2       A          T
A2      p1       G          C
A3      p1       C          C
...

如你所见,在表中我可以有同一个人几次(从不同的实验室记录)。第一个 p1 与第二个 p1 是不同的样本,我只需要选择得分最高(行数最高)的唯一样本,所以它是第一个 p1 的示例,因为它有 3,而另一个有 2。

而且我不知道如何提取该表以获得这样的结果:

gene  person  allele    allele2
A1      p1       G          C
A2      p1       A          C
A3      p1       A          T
A1      p2       G          C
A2      p2       T          T
A3      p2       G          C
A4      p2       A          T
...

我正在考虑通过 for 循环对其进行索引。例如,如果 person == above person,则添加到索引 i。如果没有,i+1。然后我会有一个小组。但是...整个 df 有 300 万行,所以在我开始之前,我决定在这里描述我的问题。也许这样做更好?

【问题讨论】:

    标签: python pandas dataframe data-science


    【解决方案1】:

    通过将Series.neSeries.shiftSeries.cumsum 进行比较来创建连续组,然后按Series.mapSeries.value_counts 进行计数:

    g = df['person'].ne(df['person'].shift()).cumsum()
    s = g.map(g.value_counts())
    
    print (s)
    0    3
    1    3
    2    3
    3    4
    4    4
    5    4
    6    4
    7    2
    8    2
    Name: person, dtype: int64
    

    最后通过GroupBy.transform 中的personSeries sboolean indexing 中的最大值比较:

    print (s.groupby(df['person']).transform('max'))
    0    3
    1    3
    2    3
    3    4
    4    4
    5    4
    6    4
    7    3
    8    3
    Name: person, dtype: int64
    
    df = df[s.groupby(df['person']).transform('max').eq(s)]
    print (df)
      gene person allele allele2
    0   A1     p1      G       C
    1   A2     p1      A       C
    2   A3     p1      A       T
    3   A1     p2      G       C
    4   A2     p2      T       T
    5   A3     p2      G       C
    6   A4     p2      A       T
    

    编辑:如果需要相同大小的第一组,例如这里组 p1 的长度相同 2 次:

    #added last row for another data test
    print (df)
      gene person allele allele2
    0   A1     p1      G       C
    1   A2     p1      A       C
    2   A3     p1      A       T
    3   A1     p2      G       C
    4   A2     p2      T       T
    5   A3     p2      G       C
    6   A4     p2      A       T
    7   A2     p1      G       C
    8   A3     p1      C       C
    9   A4     p1      C       C
    

    g = df['person'].ne(df['person'].shift()).cumsum()
    print (g)
    0    1
    1    1
    2    1
    3    2
    4    2
    5    2
    6    2
    7    3
    8    3
    9    3
    Name: person, dtype: int32
    
    #same size 3
    s = g.map(g.value_counts())
    print (s)
    0    3
    1    3
    2    3
    3    4
    4    4
    5    4
    6    4
    7    3
    8    3
    9    3
    Name: person, dtype: int64
    

    #selected first max index in s
    idx = s.groupby(df['person']).idxmax()
    print (idx)
    person
    p1    0
    p2    3
    Name: person, dtype: int64
    
    #seelcted groups g
    print (g.loc[idx])
    0    1
    3    2
    Name: person, dtype: int32
    

    #selected only matched groups
    print (g.isin(g.loc[idx]))
    0     True
    1     True
    2     True
    3     True
    4     True
    5     True
    6     True
    7    False
    8    False
    9    False
    Name: person, dtype: bool
    
    df = df[g.isin(g.loc[idx])]
    print (df)
      gene person allele allele2
    0   A1     p1      G       C
    1   A2     p1      A       C
    2   A3     p1      A       T
    3   A1     p2      G       C
    4   A2     p2      T       T
    5   A3     p2      G       C
    6   A4     p2      A       T
    

    【讨论】:

    • 哇!很好的解释,它对我有用!谢谢你!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    • 2017-04-03
    • 2020-02-22
    • 1970-01-01
    • 2023-04-02
    相关资源
    最近更新 更多