【问题标题】:How can I use groupby and filter functions on a dataframe without ending up with duplicates?如何在数据帧上使用 groupby 和 filter 函数而不会出现重复?
【发布时间】:2021-12-01 02:13:08
【问题描述】:

我有一个包含如下简单表格的 CSV 文件:

ID           PER    SEQS    SEQE    dire
AC037199.2  68.027  9674    9818    A
AC037199.2  68.919  19131   18996   A
AF243527.1  68.919  75530   75395   A
AF243527.1  70.192  97025   96928   A
XM_01194.1  73.077  133     230     A
XM_01194.1  71.605  367     525     A

就上下文而言,这些是不同 GenBank 条目的 ID,并显示与我的查询序列匹配的每个核苷酸序列的长度。 Dire 是一个占位符列

我正在使用 python(特别是 numpy 和 pandas)来:

  1. 根据 ID 列对条目进行分组
  2. 使用简单的SEQS > SEQE,确定读取是向前(增加大小)、向后(减少大小)还是两者兼而有之。然后将“可怕”列修改为 FOR 或 BACK
  3. 将这些结果打印到一个新的 CSV 文件(创造性地称为“for.csv”、“back.csv”或两者兼有 .csv)中,该文件向我显示每个 ID 的方向读取内容。

我已经设法弄清楚如何使用命令行来执行此操作(感谢 awk 和 sed!),但如果我可以在 1 个脚本中完成它而不是几行,那就太棒了。

使用来自HEREHERE 的示例,我设法获得了一个几乎可以实现这一目标的脚本:

import pandas as pd
import numpy as np
df = pd.read_csv('BLAtest.csv')
df['dire'] = np.where(df['SEQS']<df['SEQE'],'FOR','BACK') #
forw = df.groupby("ID").filter(lambda x: any(x['dire'] == 'FOR') & any(x['dire'] != 'BACK'))
back = df.groupby("ID").filter(lambda x: any(x['dire'] == 'BACK')& any(x['dire'] != 'FOR'))
both = df.groupby("ID").filter(lambda x: any((x['dire'] == 'BACK')) & any(x['dire'] == 'FOR'))
forw.to_csv('forw.csv')
back.to_csv('back.csv')
both.to_csv('test.csv')

问题:我在 for.csv 和 back.csv 中获得了条目,这些条目具有只能在 both.csv 中打印的整体。我只对都是一个方向的分组 ID 感兴趣。以上面的输出为例:

ID           PER    SEQS    SEQE    dire
AC037199.2  68.027  9674    9818    FOR
AC037199.2  68.919  19131   18996   BACK
AF243527.1  68.919  75530   75395   BACK
AF243527.1  70.192  97025   96928   BACK
XM_01194.1  73.077  133     230     FOR
XM_01194.1  71.605  367     525     FOR

在我的 for.csv 中,我得到了 AC037199.2 和 XM_01194.1,而我只想要 XM_01194.1!

如何首先修改我的脚本以避免这些重复?或者我可以按原样修改它以在之后删除这些吗?

提前感谢您的任何帮助,并希望我已经充分解释了自己。我希望我能在本周末之前完成大量数据,这只是最后的障碍!!

【问题讨论】:

    标签: python pandas dataframe numpy pandas-groupby


    【解决方案1】:

    对,想通了。事后看来这是一个愚蠢的问题,但这是为了以防其他人像我一样被卡住。

    简单地说,运行一个简单的isin 参数来运行单独的读取,这就是诀窍。我还从第 4 行和第 5 行中删除了不必要的参数,使其更简洁。所以更新的代码:

    import pandas as pd
    import numpy as np
    df = pd.read_csv('BLAtest.csv')
    df['dire'] = np.where(df['SEQS']<df['SEQE'],'FOR','BACK') 
    forw = df.groupby("ID").filter(lambda x: (x['dire'] == 'FOR').any()) 
    back = df.groupby("ID").filter(lambda x: (x['dire'] == 'BACK').any())
    both = df.groupby("ID").filter(lambda x: (x['dire'] == 'BACK').any() & (x['dire'] == 'FOR').any())
    propfor = (forw[~forw.ID.isin(both.ID)])
    propback = (back[~back.ID.isin(both.ID)])
    propfor.to_csv('forward.csv')
    propback.to_csv('backwards.csv')
    both.to_csv('test.csv')
    

    现在完成这项工作!

    我从HERE 获得了isin 参数的代码 不知道为什么我不早点这样做,但我想我一直在努力让filter 工作,我没有考虑其他选择。这可能会被压缩成更短的几行,但它可以工作,我理解为什么/如何,所以现在还可以!

    【讨论】:

      猜你喜欢
      • 2023-04-10
      • 2018-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-08
      • 2018-09-05
      • 1970-01-01
      • 2019-08-22
      相关资源
      最近更新 更多