如何用字典替换熊猫数据框中的值?

时间:2019-05-18 17:26:59

标签: python pandas dataframe

我对熊猫和替换值有疑问。 我有一张桌子,上面放着动物,它们的等位基因看起来是这样:

Name   User A1_Top  A2_Top
stefan1 721    A    C   
stefan2 721    A    G
stefan3 331    T    T   
stefan4 331    C    G
stefan5 331    A    A
stefan6 721    G    G   

我需要通过每行的特定键来更改Top1和Top2的值。

例如:if values in same rows will be = C & A, I will replace it to A & B, if row == TT will be BB等(密钥在下面的if / else中)。

我在另一篇文章中得到了一个答案,如何用字典来做,但是我不能用双重条件处理(如果这是一个条件,例如,如果第一行中的A替换为B,就可以了) )。所以我只是将其放入if / else循环中,并且可以工作...我的意思是可以工作,直到文件很大为止。现在太慢了。 300mb文件可以在标准桌面上处理30分钟。

这就是我的代码现在的样子:

def ATCG_to_AB(df):
x = 0
for i in range(lenFor):
    if df['A1_TOP'].iloc[i] == 'A' and df['A2_TOP'].iloc[i] =='C':
        df['A1_TOP'].iloc[i] = 'A'
        df['A2_TOP'].iloc[i] ='B'
    elif df['A1_TOP'].iloc[i] == 'A' and df['A2_TOP'].iloc[i] =='G':
        df['A1_TOP'].iloc[i] = 'A'
        df['A2_TOP'].iloc[i] ='B'
    elif df['A1_TOP'].iloc[i] == 'A' and df['A2_TOP'].iloc[i] =='T':
        df['A1_TOP'].iloc[i] = 'A'
        df['A2_TOP'].iloc[i] ='B'
    elif df['A1_TOP'].iloc[i] == 'C' and df['A2_TOP'].iloc[i] =='G':
        df['A1_TOP'].iloc[i] = 'A'
        df['A2_TOP'].iloc[i] ='B'
    elif df['A1_TOP'].iloc[i] == 'A' and df['A2_TOP'].iloc[i] =='A':
        df['A1_TOP'].iloc[i] = 'A'
        df['A2_TOP'].iloc[i] ='A'
    elif df['A1_TOP'].iloc[i] == 'C' and df['A2_TOP'].iloc[i] =='C':
        df['A1_TOP'].iloc[i] = 'B'
        df['A2_TOP'].iloc[i] ='B'
    elif df['A1_TOP'].iloc[i] == 'G' and df['A2_TOP'].iloc[i] =='G':
        df['A1_TOP'].iloc[i] = 'B'
        df['A2_TOP'].iloc[i] ='B'
    elif df['A1_TOP'].iloc[i] == 'T' and df['A2_TOP'].iloc[i] =='T':
        df['A1_TOP'].iloc[i] = 'B'
        df['A2_TOP'].iloc[i] ='B'
    else:
        print(x,". Something is wrong in line: ", i)
        x+=1

X-计算错误。 而且我知道,该代码很丑陋,所以我尝试使用字典方法。我的尝试:

L = [('A', 'C', 'A', 'B'),('A', 'G', 'A', 'B'),('A', 'T', 'A', 'B'),
 ('C', 'G', 'A', 'B'),('A', 'A', 'A', 'A'),('C', 'C', 'B', 'B'),
 ('G', 'G', 'B', 'B'),('T', 'T', 'B', 'B')]


for x in L:
    a.loc[(df[2] == x[0]) & (df[3] == x[1]), [2,3]] = [x[2], x[3]]

但是我的输出不好。唯一的A1_top已更改,通常它是一个不好的符号。有人可以帮我把丑陋的代码翻译成字典并解释吗?我是否认为这将是一个更快的解决方案?

当然可以期待输出(为清晰起见,下面没有标题)

name   User A1_Top  A2_Top
    stefan1 721    A    B   
    stefan2 721    A    B   
    stefan3 331    B    B   
    stefan4 331    A    B
    stefan5 331    A    A
    stefan6 721    B    B   

1 个答案:

答案 0 :(得分:2)

一个简单的技巧,并不是说最好的,但它可以起作用: [创建虚拟列以进行映射或df[col].apply]

df['combined'] = df['A1_Top']+"|"+df['A2_Top']

  A1_Top A2_Top combined
0      A      C      A|C
1      A      G      A|G
2      T      T      T|T
3      C      G      C|G
4      A      A      A|A
5      G      G      G|G

创建字典,映射所有需求:我在这里给1

map_dict = {}
map_dict['A|C'] = 'B|C'
.
.
.

df['new_values'] = df['combined'].apply(lambda x:map_dict[x] if x in map_dict.keys() else x)

  A1_Top A2_Top combined new_values
0      A      C      A|C        B|C
1      A      G      A|G        A|G
2      T      T      T|T        T|T
3      C      G      C|G        C|G
4      A      A      A|A        A|A
5      G      G      G|G        G|G

df['new_a1_top'] = df['new_values'].apply(lambda x: x.split('|')[0])
df['new_a2_top'] = df['new_values'].apply(lambda x: x.split('|')[1])

  A1_Top A2_Top combined new_values new_a1_top new_a2_top
0      A      C      A|C        B|C          B          C
1      A      G      A|G        A|G          A          G
2      T      T      T|T        T|T          T          T
3      C      G      C|G        C|G          C          G
4      A      A      A|A        A|A          A          A
5      G      G      G|G        G|G          G          G