2017-07-21 105 views
2

我有一個df在下面的格式約70000列和540行。所有值都是0.0,0.5或1.0。刪除列數值滿足條件(大熊貓)

VAR   1_139632_G 1_158006_T 1_172595_A 1_564650_A 1_564652_G \ 
SRR4216489   0.5   0.5   0.5   0.5   0.5 
SRR4216786   0.5   0.5   0.5   0.5   0.5 
SRR4216628   0.5   0.0   1.0   0.0   0.0 
SRR4216456   0.5   0.5   0.5   0.5   0.5 
SRR4216393   0.5   0.5   0.5   0.5   0.5 

我想刪除'0.5'值的數量只比行數少1的所有列。到目前爲止,我嘗試過;

total_samples = len(df.index) # Gets the number of rows 
df_col_05 = df[df == 0.5].count() # returns a df with column-wise counts 
df_col_05 = df_col_05.where(df_col_05 < (total_samples-1)) #replaces with Nan where the condition isn't met 

我要的是我原來的DF把所有的cols去除其中df_col_05的值> =(total_samples-1),所以基本上去除地方「df_col_05」有一個NaN的,但我不知道該怎麼辦這個?

我敢肯定,這應該比自己多一點大熊貓經驗的人很容易(我開始前幾天)

回答

4

您可以使用boolean indexingloc用於過濾列,也能更好的使用sum爲在DataFrame得到True小號size

#if first column is not index set it 
df = df.set_index('VAR') 
df1 = df.loc[:, (df == 0.5).sum() >= len(df.index)-1] 

樣品

#changed values in last 2 columns 
print (df) 
      VAR 1_139632_G 1_158006_T 1_172595_A 1_564650_A 1_564652_G 
0 SRR4216489   0.5   0.5   0.5   0.0   0.0 
1 SRR4216786   0.5   0.5   0.5   0.0   0.5 
2 SRR4216628   0.5   0.0   1.0   0.0   0.0 
3 SRR4216456   0.5   0.5   0.5   0.5   0.5 
4 SRR4216393   0.5   0.5   0.5   0.5   0.5 

print (df[df == 0.5].count()) 
VAR   0 
1_139632_G 5 
1_158006_T 4 
1_172595_A 4 
1_564650_A 2 
1_564652_G 3 
dtype: int64 

print ((df == 0.5).sum()) 
VAR   0 
1_139632_G 5 
1_158006_T 4 
1_172595_A 4 
1_564650_A 2 
1_564652_G 3 
dtype: int64 

#if first column is not index set it 
df = df.set_index('VAR') 

print ((df == 0.5).sum() >= len(df.index)-1) 
1_139632_G  True 
1_158006_T  True 
1_172595_A  True 
1_564650_A False 
1_564652_G False 
dtype: bool 

print (df.loc[:, (df == 0.5).sum() >= len(df.index)-1]) 
      1_139632_G 1_158006_T 1_172595_A 
VAR           
SRR4216489   0.5   0.5   0.5 
SRR4216786   0.5   0.5   0.5 
SRR4216628   0.5   0.0   1.0 
SRR4216456   0.5   0.5   0.5 
SRR4216393   0.5   0.5   0.5 

而不​​另一種解決方案,只需要定義哪些總是需要在輸出列:

m = (df == 0.5).sum() >= len(df.index)-1 
print (m) 
VAR   False 
1_139632_G  True 
1_158006_T  True 
1_172595_A  True 
1_564650_A False 
1_564652_G False 
dtype: bool 

need_cols = ['VAR'] 
m.loc[need_cols] = True 
print (m) 
VAR   True 
1_139632_G  True 
1_158006_T  True 
1_172595_A  True 
1_564650_A False 
1_564652_G False 
dtype: bool 

print (df.loc[:, m]) 
      VAR 1_139632_G 1_158006_T 1_172595_A 
0 SRR4216489   0.5   0.5   0.5 
1 SRR4216786   0.5   0.5   0.5 
2 SRR4216628   0.5   0.0   1.0 
3 SRR4216456   0.5   0.5   0.5 
4 SRR4216393   0.5   0.5   0.5 

類似溶液分別過濾柱,然後選擇:

print (df[df.columns[m]]) 
      VAR 1_139632_G 1_158006_T 1_172595_A 1_564652_G 
0 SRR4216489   0.5   0.5   0.5   0.0 
1 SRR4216786   0.5   0.5   0.5   0.5 
2 SRR4216628   0.5   0.0   1.0   0.0 
3 SRR4216456   0.5   0.5   0.5   0.5 
4 SRR4216393   0.5   0.5   0.5   0.5 
+0

大!解決它 - 非常感謝!因爲我是熊貓新手,你是否介意澄清代碼的幾個小部分在做什麼。這是「df.loc [:,」使它指向同一時間的所有列和所有行?我認爲它需要一個大小匹配的布爾數組與共享索引,這是'm'進來的地方? – user3062260

+0

是的,確切地說。經典的布爾索引更簡單,並通過類似'df = df [df ['col'] <5]'的布爾掩碼來移除行。但是爲了移除需要loc的列,首先':'表示所有行,然後布爾掩碼根據條件刪除列。並且需要與df相同的掩碼大小,否則會引發錯誤。所以祝大家好運,如果需要更多解釋,請告訴我。愉快的週末! – jezrael