2017-05-03 81 views
2

我有一個數據幀,它看起來像下面的多個數據幀,交換列之間行數據幀中基於條件

foo = pd.DataFrame(
     [['chr1',2,1,'+',0.1,'NA','TSS1'], 
     ['chr2',3,4,'-',0.03,'NA','TSS2'], 
     ['chr3',7,6,'+',0.7,'NA','TSS3']], 
     columns = ('CHR', 'start', 'end','Strand','Peak','Ratio','Annotation') 
    ) 
foo 
    CHR start end Strand Peak Ratio Annotation 
0 chr1 2 1 + 0.10 NA TSS1 
1 chr2 3 4 - 0.03 NA TSS2 
2 chr3 7 6 + 0.70 NA TSS3 

而且我的目標列之間進行切換的開始和結束,也就是說,如果列開局大於列結束時,我需要它交換其位置,並保持其餘的列完好無損或就這樣。

這樣的事情,

def fun(x): 
    if df['start']> df['End'] 
print df[['CHR','end','start','Strand','Peak','Ratio','Annotation']] 
    else 
    return df 

因爲我需要以上功能不起作用。 最後,我需要一個數據幀,

CHR start end Strand Peak Ratio Annotation 
0 chr1 1 2 + 0.10 NA TSS1 
1 chr2 3 4 - 0.03 NA TSS2 
2 chr3 6 7 + 0.70 NA TSS3 

任何幫助或者更好的建議將是巨大的。另外,我有大量的多個數據幀。

回答

2

我認爲simplier是:

foo[['start','end']] = foo[['start','end']].apply(np.sort, axis=1) 
print (foo) 
    CHR start end Strand Peak Ratio Annotation 
0 chr1  1 2  + 0.10 NA  TSS1 
1 chr2  3 4  - 0.03 NA  TSS2 
2 chr3  6 7  + 0.70 NA  TSS3 

minmax另一種解決方案:

df1 = foo[['start','end']] 
foo['start'] = df1.min(axis=1) 
foo['end'] = df1.max(axis=1) 
print (foo) 
    CHR start end Strand Peak Ratio Annotation 
0 chr1  1 2  + 0.10 NA  TSS1 
1 chr2  3 4  - 0.03 NA  TSS2 
2 chr3  6 7  + 0.70 NA  TSS3 

解條件和numpy.where,但需要numpy.column_stack用於重複mask爲每列:

b = foo['start'] < foo['end'] 
foo[['start','end']] = np.where(np.column_stack([b,b]), 
           foo[['start','end']], 
           foo[['end','start']]) 
print (foo) 
    CHR start end Strand Peak Ratio Annotation 
0 chr1  1 2  + 0.10 NA  TSS1 
1 chr2  3 4  - 0.03 NA  TSS2 
2 chr3  6 7  + 0.70 NA  TSS3 

如果需要自定義函數apply是沒有必要的:

def fun(foo): 
    b = foo['start'] < foo['end'] 
    foo[['start','end']] = np.where(np.column_stack([b,b]), 
            foo[['start','end']], 
            foo[['end','start']]) 
    return foo 

print (fun(foo)) 
    CHR start end Strand Peak Ratio Annotation 
0 chr1  1 2  + 0.10 NA  TSS1 
1 chr2  3 4  - 0.03 NA  TSS2 
2 chr3  6 7  + 0.70 NA  TSS3 
+0

沒有,對換,應根據不只是改變列的位置的條件。如果'end'列小於'start'列,則交換這些行,否則保持原樣。此外,上述命令不適用於更大的數據框 – user1017373

+0

也有可能使它作爲一個功能,我可以用它來df.apply(func) – user1017373

+0

嗯,我認爲這是可能的,但並不那麼容易。但是給我一些時間。 – jezrael