我有一个44列和60,000行的数据框。如果它有0到75%的列,我想删除这些行。这个75%:例如在我的情况下,44列中的33列。所以我在R中尝试了以下功能 如,
filter <- apply(df, 1,function(x) any(x[1:33]!=0) && any(x[34:44]!=0) )
df = df[filter,]
它非常适合我要求的那些专栏。但问题是我的数据框有很多行,其值如此,对于某些行,在备用模型中有零,即一列其数值则为零,依此类推。这有时超过33列,上面的函数避免了这些行。
到目前为止,我在R中尝试过,我可以在熊猫中尝试的任何解决方案也都很棒..我知道当pandas中的所有值都不等于零时
df[(df != 0).all(1)]
以下是我的数据框架的样子,
dim(df)
[1] 57905 44
head(df)
ID Pe_1 Pe_2 Pe_3 Pe_4 Pe_5 Pe_6 Pe_7 Pe_8 Pe_9 Pe_10 Pe_11 Pe_12 Pe_13 Pe_14 Pe_15 Pe_16 Pe_17 Pe_18 Pe_19 Pe_20 Pe_21 Pe_22 Pe_23 Pe_24 Pe_25 Pe_26 Pe_27 Pe_28 Pe_29 Pe_30 Pe_31 Pe_32 Pe_33 Pe_34 Pe_35 Pe_36 Pe_37 Pe_38 Pe_39 Pe_40 Pe_41 Pe_42 Pe_43 Pe_44
ENSG1 0 0 1 0 0 2 2 1 0 0 0 1 0 3 3 0 1 0 2 0 2 3 1 2 0 2 0 0 0 0 0 2 0 0 0 0 2 0 0 2 0 3 1 3
ENSG2 274 293 300 273 229 124 427 291 274 561 128 506 342 540 376 422 411 190 723 224 303 316 766 697 251 167 271 361 325 133 215 274 217 366 227 579 337 254 570 188 143 363 250 359
ENSG3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ENSG4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ENSG5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ENSG6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ENSG7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ENSG8 0 1 0 1 1 1 0 2 0 0 0 1 1 1 0 1 0 0 0 0 0 1 1 1 2 1 0 3 0 1 1 2 0 0 0 0 0 0 1 1 0 0 1 1
ENSG9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ENSG10 3 2 4 6 21 6 6 13 3 1 1 6 10 4 2 0 1 0 0 0 4 2 5 3 25 9 7 10 7 5 3 0 0 5 1 8 4 5 0 4 1 3 2 4
ENSG11 277 43 79 216 1170 174 213 1303 564 14 53 76 170 1016 32 19 69 69 50 21 75 31 560 86 2668 604 513 303 1378 109 219 172 10 1031 276 242 1587 217 76 43 450 81 502 99
任何建议/帮助都会很棒
答案 0 :(得分:7)
似乎您要删除超过75%0
的行。例如,保留至少有25%非零值的行。
在R
:
df = data.frame(a=c(1,8,0), b=c(0,2,0), c=c(0,0,1), d=c(4,4,0))
df[rowMeans(df!=0)>0.25, ] # or df[rowMeans(df==0)<0.75, ]
# a b c d
#1 1 0 0 4
#2 8 2 0 4
在Pandas
:
df = pd.DataFrame({'a':[1,8,0],'b':[0,2,0],'c':[0,0,1], 'd':[4,4,0]})
# In [198]: df
# Out[198]:
# a b c d
#0 1 0 0 4
#1 8 2 0 4
#2 0 0 1 0
df[df.astype('bool').mean(axis=1)>=0.25] # or df[(~df.astype('bool')).mean(axis=1)<0.75]
#Out[199]:
# a b c d
#0 1 0 0 4
#1 8 2 0 4
答案 1 :(得分:3)
试试这个(熊猫):
df[(df==0).sum(axis=1)/len(df.columns) <= 0.75]
答案 2 :(得分:3)
Pandas方法,这里我们使用0
将df与sum
和axis=1
行进行比较,这将生成一个Series
,其中包含0个值的计数,我们将其与行长度的75%进行比较并过滤df:
In [14]:
df[(df == 0).sum(axis=1) < df.shape[1] * 0.75]
Out[14]:
ID Pe_1 Pe_2 Pe_3 Pe_4 Pe_5 Pe_6 Pe_7 Pe_8 Pe_9 ... \
0 ENSG1 0 0 1 0 0 2 2 1 0 ...
1 ENSG2 274 293 300 273 229 124 427 291 274 ...
7 ENSG8 0 1 0 1 1 1 0 2 0 ...
9 ENSG10 3 2 4 6 21 6 6 13 3 ...
10 ENSG11 277 43 79 216 1170 174 213 1303 564 ...
Pe_35 Pe_36 Pe_37 Pe_38 Pe_39 Pe_40 Pe_41 Pe_42 Pe_43 Pe_44
0 0 0 2 0 0 2 0 3 1 3
1 227 579 337 254 570 188 143 363 250 359
7 0 0 0 0 1 1 0 0 1 1
9 1 8 4 5 0 4 1 3 2 4
10 276 242 1587 217 76 43 450 81 502 99
[5 rows x 45 columns]
答案 3 :(得分:1)
或者@ colonel-beauvel使用rowMeans
,你可以使用rowSums
。
df[rowSums(df[, -1] > 0) / (ncol(df)-1) >= 0.75,]
rowSums
将所有行添加到一起(它和rowMeans
非常快)。ncol
返回df的列数(从中减去1)。rowSums
和ncol
的比率与0.75进行比较,返回逻辑。此逻辑用于对行进行子集化。
答案 4 :(得分:0)
简单的代码,它应该工作:
for i in df:
iLength = 0
countZeros = 0
for j in df:
iLength += 1
if i[j] == 0:
countZeros += 1
zeroRate = countZeros / iLength
if zeroRate >= 0.75:
#DeleteRow
答案 5 :(得分:-2)
R解决方案(希望如此)
我想我得到了这个,跳过你想要的一块。这里和那里之间的代码都是在上下文中的所有代码,并且可以在R中工作。
MakeDF.R <- function(CustomVector,n){
#just a function to make a sample df
NewDF <- data.frame(matrix(nrow=n,ncol=length(CustomVector)))
colnames(NewDF) <- CustomVector
return(NewDF)
}
制作数据框
DF<-MakeDF.R(c(1:44),10)
#sample df with 44 rows
添加一些带零的行
DF[c(5,6,7),] <- c(1:44)*0
#add sample zero rows
现在你需要的位。
RemoveRows <- lapply(1:nrow(DF),function(i){
RemoveRow_i = 0
if(
length(which(DF[i,] == 0)) > (ncol(DF) * 0.75) ){
#above is the "more than 75% zero columns step
RemoveRow_i = i #select this row as one to be removed
}
RemoveRow_i
#return either the row number or zero
})
这为我们提供了要删除的行列表。现在我们需要清理该列表(删除零)
RemoveRows = RemoveRows[RemoveRows > 0]
#Leaves no zeroes in the list
清理清单后,我们可以删除数据
CleanedDF <- DF[-do.call(rbind,RemoveRows)[,1],]
#the do.call(rbind....) is returning a 1 column dataframe.
#So the first column is the vector of rows we want to remove.
#the -c(row numbers) removes rows. df[-1,] would delete the first row
#df[-c(1,2),] would delete the first two rows