大熊猫-从df提取多个重复到另一个

时间:2019-09-13 11:28:24

标签: python pandas dataframe

DF:

geneName   HumanNumber
AHHD        585447
GDFGRE      585447
HFHFR       585447
REWEGD      585447
FDSDD       585447
AHHD        42334
GHRG        42334
REWEGD      42334
FDSDD       42334
...
HFHFR       585447
GDFGRE      585447
AHHD        585447
REWEGD      585447
FDSDD       585447
...

HumanNumber是HumanID,geneName是经过检查的基因。在数据框中,我有80k人。每个人可以检查120-200个基因。

U可以看到一个人可以被检查2次或更多次。在此示例中,我humanID 585447在两个不同的机构进行了两次检查。因此,需要将其分析为两个不同的人,但是我不能只更改HumanNumber-因为它需要与源文件相同才能进行后续处理。

所以我需要为所有样品创建分析。复制的内容不能在同一结果文件中。它们需要分开。

所以我的想法是:  -添加新列-由DF循环的每个indicationCol的{​​{1}}。  -然后df看起来会:

HumanNumber

现在我只能按ID提取HumanNumbers,如果df不是唯一的,则可以用geneName HumanNumber indicationCol AHHD 585447 1 GDFGRE 585447 1 HFHFR 585447 1 REWEGD 585447 1 FDSDD 585447 1 AHHD 42334 2 GHRG 42334 2 REWEGD 42334 2 FDSDD 42334 2 ... HFHFR 585447 3 GDFGRE 585447 3 AHHD 585447 3 REWEGD 585447 3 FDSDD 585447 3 ... 提取第二个,然后将其丢给另一个df。

df

indicationCol

df_duplicates:

geneName   HumanNumber   indicationCol   
    AHHD        585447            1
    GDFGRE      585447            1
    HFHFR       585447            1
    REWEGD      585447            1
    FDSDD       585447            1
    AHHD        42334             2
    GHRG        42334             2
    REWEGD      42334             2
    FDSDD       42334             2
    ...

所以我写了一个代码:

HFHFR       585447            3
GDFGRE      585447            3
AHHD        585447            3
REWEGD      585447            3
FDSDD       585447            3

这是可行的(尽管我从熊猫那里收到了复制警告),但时间太长了。 name = '585447' a = 0 df['indicationCol'] = 99999999 df= df.copy() for i in range(len(df)): if df[4].iloc[i] == name: df['indicationCol'].iloc[i] = a else: a = a+1 name = df[4].iloc[i] df['wskaznik'].iloc[i] = a 20分钟后。整个df有15,012,022行。

所以..我该怎么做才能升级我的代码。我希望是解决这个问题的更好方法,我只是不知道。

有人可以帮助我吗?

2 个答案:

答案 0 :(得分:2)

如果您希望这种按时间顺序表示重复的方式,我们可以使用diffcumsum

df['indicationCol'] = df['HumanNumber'].diff().fillna(0).ne(0).cumsum().add(1)

或将shiftcumsum

df['indicationCol'] = df['HumanNumber'].ne(df['HumanNumber'].shift()).cumsum()

输出

   geneName  HumanNumber  indicationCol
0      AHHD       585447              1
1    GDFGRE       585447              1
2     HFHFR       585447              1
3    REWEGD       585447              1
4     FDSDD       585447              1
5      AHHD        42334              2
6      GHRG        42334              2
7    REWEGD        42334              2
8     FDSDD        42334              2
9     HFHFR       585447              3
10   GDFGRE       585447              3
11     AHHD       585447              3
12   REWEGD       585447              3
13    FDSDD       585447              3

我建议使用GroupBy上的HumanNumber和新列indicationCol来访问每个唯一组:

for _, grp in df.groupby(['HumanNumber', 'indicationCol'], sort=False):
    print(grp, '\n')

  geneName  HumanNumber  indicationCol
0     AHHD       585447              1
1   GDFGRE       585447              1
2    HFHFR       585447              1
3   REWEGD       585447              1
4    FDSDD       585447              1 

  geneName  HumanNumber  indicationCol
5     AHHD        42334              2
6     GHRG        42334              2
7   REWEGD        42334              2
8    FDSDD        42334              2 

   geneName  HumanNumber  indicationCol
9     HFHFR       585447              3
10   GDFGRE       585447              3
11     AHHD       585447              3
12   REWEGD       585447              3
13    FDSDD       585447              3 

答案 1 :(得分:1)

对您问题的书面答复 您可以通过计数器col来完成此过程:

df['indicatorCol'] = (df
                      .duplicated()
                      .to_frame()
                      .groupby([df.HumanNumber, df.geneName])
                      .apply(lambda x: x.cumsum())

结果:

    geneName    HumanNumber indicatorCol
0   AHHD    585447.0    1
1   GDFGRE  585447.0    1
2   HFHFR   585447.0    1
3   REWEGD  585447.0    1
4   FDSDD   585447.0    1
5   AHHD    42334.0 0
6   GHRG    42334.0 0
7   REWEGD  42334.0 0
8   FDSDD   42334.0 0
10  HFHFR   585447.0    2
11  GDFGRE  585447.0    2
12  AHHD    585447.0    2
13  REWEGD  585447.0    2
14  FDSDD   585447.0    2

更快捷的方法

您可以使用pandas.DataFrame.duplicated()完成相同的目标,这实际上是重复的指标。

df[df.duplicated(keep='first')] # First to get the first entry and label others as duplications
    geneName    HumanNumber
10  HFHFR   585447.0
11  GDFGRE  585447.0
12  AHHD    585447.0
13  REWEGD  585447.0
14  FDSDD   585447.0
unique_df = df[~df.duplicated(keep='first')] # Unique first occurances
duplicated_df = df[df.duplicated(keep='first')] #Duplicates of Unique

您还可以使用df[~df.duplicated(keep='first')]与第一个DataFrame的重复值。

keep argument的一些解释:

  

保持:{'first','last',False},默认为'first'

     
      
  • first:将第一个重复项标记为“ True”。
  •   
  • last:将最后一次出现的重复项标记为True。
  •   
  • False:将所有重复项标记为True。
  •