Python 如何根据其他列的多个偶然事件转换列?

Python 如何根据其他列的多个偶然事件转换列?,python,pandas,Python,Pandas,我有一个数据帧: df = pd.DataFrame({'REF':list('GCTT'), 'ALT':list('AACG'), 'A1':['0/1','0/1','0/0','0/1'], 'A2':['1/1','0/1','0/1','0/0']}) 我想根据REF和ALT列中的值转换列A1和A2。因此,第0行中的列A1和A2应为GA和AA。ie丢失“/”并将0s替换为G,1s替换为A。接下来,第1行应将

我有一个数据帧:

df = pd.DataFrame({'REF':list('GCTT'), 'ALT':list('AACG'),
                   'A1':['0/1','0/1','0/0','0/1'],
                   'A2':['1/1','0/1','0/1','0/0']})
我想根据REF和ALT列中的值转换列A1和A2。因此,第0行中的列A1和A2应为GA和AA。ie丢失“/”并将0s替换为G,1s替换为A。接下来,第1行应将0s替换为C,将1s替换为A。然后按照下一行的模式获得:

  REF ALT  A1   A2
0   G   A  GA  AA
1   C   A  CA  CA
2   T   C  TT  TC
3   T   G  TG  TT

在我的数据中有数百列A:A1、A2……An-1、An。因此,解决方案需要在所有列中都可复制。

我认为可能有更好的方法来实现这一点,但这是可行的。 如果是性能问题,请告诉我

acols = df.drop(['REF', 'ALT'], axis=1).columns

for i in acols:
    df.loc[df[i] == '0/0', i] = df['REF'] * 2
    df.loc[df[i] == '0/1', i] = df['REF'] + df['ALT']
    df.loc[df[i] == '1/1', i] = df['ALT'] * 2
另一种选择

for i in acols:
    df[i] = df[i].replace(to_replace='0/0', value=df['REF']+df['REF'])
    df[i] = df[i].replace(to_replace='0/1', value=df['REF']+df['ALT'])
    df[i] = df[i].replace(to_replace='1/1', value=df['ALT']+df['ALT'])

您只有4个组合
0
1
,因此我想您可以尝试
np。选择

df1 = df.drop(['REF', 'ALT'], axis=1)

#conditions
combo = ['0/0', '0/1', '1/0', '1/1']
conds = [df1.eq(x) for x in combo]

#selections
s00 = (df.REF * 2).to_numpy()[:,None]
s11 = (df.ALT * 2).to_numpy()[:,None]
s01 = (df.REF + df.ALT).to_numpy()[:,None]

df.loc[:, df1.columns.tolist()] = np.select(conds , [s00, s01, s01[:,::-1], s11], np.nan)

Out[260]:
  REF ALT  A1  A2
0   G   A  GA  AA
1   C   A  CA  CA
2   T   C  TT  TC
3   T   G  TG  TT
编辑:解决方案2.,使用索引:

# helper structs:
ncbscols= ["REF","ALT"]
cols= df.columns.difference(ncbscols)

ii= pd.MultiIndex.from_product([list("ACGT"),list("ACGT"),["0/0","0/1","1/1","1/0"] ])
ser= pd.Series( [t[2].replace("/","").replace("0",t[0]).replace("1",t[1]) for t in ii ],  index=ii )

# the main calculation:
for c in cols:
    mi= pd.MultiIndex.from_arrays([ df.REF.values,df.ALT.values,df[c].values ])
    df[c]= ser[mi].values


ser:
 A  A  0/0    AA
      0/1    AA
      1/1    AA
      1/0    AA
   C  0/0    AA
             ..
T  G  1/0    GT
   T  0/0    TT
      0/1    TT
      1/1    TT
      1/0    TT
Length: 64, dtype: object 

df:
  REF ALT  A1  A2
0   G   A  GA  AA
1   C   A  CA  CA
2   T   C  TT  TC
3   T   G  TG  TT

是否所有的<代码> A <代码>列0和1 IR的组合,除了“代码> REF < /代码>和<代码> ALT之外,还有更多的列要考虑吗?是的,所有0个或1个,只需要考虑REF和ALT <代码>行。这似乎根本不正确,因为您也在执行
split
,我假设您循环每个col以进行替换。你确定你是对的-我把%timeit放错地方了,你的方法很快。谢谢
df1 = df.drop(['REF', 'ALT'], axis=1)

#conditions
combo = ['0/0', '0/1', '1/0', '1/1']
conds = [df1.eq(x) for x in combo]

#selections
s00 = (df.REF * 2).to_numpy()[:,None]
s11 = (df.ALT * 2).to_numpy()[:,None]
s01 = (df.REF + df.ALT).to_numpy()[:,None]

df.loc[:, df1.columns.tolist()] = np.select(conds , [s00, s01, s01[:,::-1], s11], np.nan)

Out[260]:
  REF ALT  A1  A2
0   G   A  GA  AA
1   C   A  CA  CA
2   T   C  TT  TC
3   T   G  TG  TT
I wonder how fast this solution is with your data:

for col in ["A1","A2"]: 
        df[col]= df[col].str.split("/",expand=True) \
                        .replace(["0","1"],[df.REF,df.ALT]) \
                        .agg("".join,axis=1) 

df                                                                                                                  

  REF ALT  A1  A2
0   G   A  GA  AA
1   C   A  CA  CA
2   T   C  TT  TC
3   T   G  TG  TT
# helper structs:
ncbscols= ["REF","ALT"]
cols= df.columns.difference(ncbscols)

ii= pd.MultiIndex.from_product([list("ACGT"),list("ACGT"),["0/0","0/1","1/1","1/0"] ])
ser= pd.Series( [t[2].replace("/","").replace("0",t[0]).replace("1",t[1]) for t in ii ],  index=ii )

# the main calculation:
for c in cols:
    mi= pd.MultiIndex.from_arrays([ df.REF.values,df.ALT.values,df[c].values ])
    df[c]= ser[mi].values


ser:
 A  A  0/0    AA
      0/1    AA
      1/1    AA
      1/0    AA
   C  0/0    AA
             ..
T  G  1/0    GT
   T  0/0    TT
      0/1    TT
      1/1    TT
      1/0    TT
Length: 64, dtype: object 

df:
  REF ALT  A1  A2
0   G   A  GA  AA
1   C   A  CA  CA
2   T   C  TT  TC
3   T   G  TG  TT