根据另一个列中的键更改列的值

时间:2019-07-29 12:20:58

标签: python pandas dataframe

我有一个独特的frame,如下所示:

GeneName      position      chromosome
ARS-1155      55562           14
ARS-2131      3132             4
ARS-4412      233              1
ARS-1121      411              5
...

我有一个base的csv,有几百万行,看起来是:

BaseGeneName      base_pos      base_chrom
ARS-1155      5222            5
ARS-1155      5222            5
ARS-1323      32111           5 
ARS-1233      51112           1
ARS-1121      1222            5
...

如U所见,第二帧不是唯一的,它可以包含GenesNames,这些容器也包含frame。但是在碱基上它们可以具有不同的位置和染色体数目。

Base只是一个新的GeneBank,我需要将职位从我的框架升级到Base

所以,如果我有

 ARS-1155      55562           14

frame中应更改为

ARS-1155      5222            5

,并将附加到UpgradedDF。如果frame中有一些GeneName,而base中没有,则应移到旧位置的UndefinedDF中。

我用语句编写了一个for循环。像这样: (我记不太清,在电话上写东西)

listOfGenName = [allGeneNames from df]

for i in len(base):
  a = base.where(base.baseGenName == i.GenName).dropna()
  if a > 0:
    UpgradedDF.append(a)
  else:
    UndefinedDF.append(a)

然后我放下重复项。

但是操作时间太长。我的意思是我添加了print(i +"/"+len(base)),并计算出该操作将运行几天!

我尝试将其合并,但未成功。有人可以给我建议吗?

编辑: 恢复: UpgradedDF仅应是framebase中存在的基因。因此,如果frame中的Abase中的base[A]应该移至UpgradedDF,如果帧中的A和base中的{ {t {1}}不可移动。如果A中不是frame,而Abase则什么也没有发生。

2 个答案:

答案 0 :(得分:2)

我们可以执行以下操作:

  1. 将重复项放入base
  2. Left merge带有底框的框架
  3. 替换框架中基本列的值
base = base.drop_duplicates()

frame = frame.merge(base, left_on='GeneName', right_on='BaseGeneName', how='left')
frame['position'] = frame['base_pos'].fillna(frame['position'])
frame['chromosome'] = frame['base_chrom'].fillna(frame['chromosome'])

frame = frame.loc[:, :'chromosome']

输出

   GeneName  position  chromosome
0  ARS-1155    5222.0         5.0
1  ARS-2131    3132.0         4.0
2  ARS-4412     233.0         1.0
3  ARS-1121    1222.0         5.0

答案 1 :(得分:1)

如果我正确理解... 听起来base位于GeneName中的所有frame都需要放入UpgradedDF

UpgradedDF = base[base.BaseGeneName.isin(frame.GeneName)].drop_duplicates()

所有不在frame中的base都需要转到UndefinedDF

UndefinedDF = frame[~frame.GeneName.isin(base.BaseGeneName)]