2017-07-21 79 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