Удалить столбцы и строки с определенным процентом от панд 0 - PullRequest
2 голосов
/ 26 марта 2019

У меня есть двумерные данные (Column-Cell1, Cell2 .., Row-Gene1, Gene2 ..), в которых я хочу удалить строки с нулями 99% и с результирующими столбцами удаления матрицы с 99% нулей в них,Я написал следующий код, чтобы сделать то же самое, однако, поскольку матрица очень большая, ее запуск занимает много времени.Есть ли лучший способ подойти к этому вопросу?

import pandas as pd
import numpy as np

def read_in(matrix_file):
    matrix_df=pd.read_csv(matrix_file,index_col=0)
    return(matrix_df)

def genes_less_exp(matrix_df):
    num_columns=matrix_df.shape[1]
    for index, row in matrix_df.iterrows():
        zero_els=np.count_nonzero(row.values==0)
        gene_per_zero=(float(zero_els)/float(num_columns))*100
        if gene_per_zero >= 99:
            matrix_df.drop([index],axis=0,inplace=True)
    return(matrix_df)

def cells_less_exp(matrix_df):
    num_rows=matrix_df.shape[0]
    for label,content in matrix_df.iteritems():
        zero_els=np.count_nonzero(content.values==0)
        cells_per_zero=(float(zero_els)/float(num_rows))*100
        if cells_per_zero >= 99:
            matrix_df.drop(label,axis=1,inplace=True)
    return(matrix_df)


if __name__ == "__main__":
    matrix_df=read_in("Data/big-matrix.csv")
    print("original:"+str(matrix_df.shape))
    filtered_genes=genes_less_exp(matrix_df)
    print("filtered_genes:"+str(filtered_genes.shape))
    filtered_cells=cells_less_exp(filtered_genes)
    print("filtered_cells:"+str(filtered_cells.shape))
    filtered_cells.to_csv("abi.99.percent.filtered.csv", sep=',')

1 Ответ

1 голос
/ 26 марта 2019

Это проще, если вы перефразируете свой вопрос, чтобы «оставить тех, у кого меньше 99% 0».

def drop_almost_zero(df, percentage):
    row_cut_off = int(percentage/100*len(df.columns))
    df = df[(df==0).sum(axis='columns') <= row_cut_off]

    column_cut_off = int(percentage/100*len(df)) 
    b = (df == 0).sum(axis='rows')
    df = df[ b[ b <= column_cut_off].index.values ]

    return df


#test
size = 50
percentage = 90

rows = size//2
columns = size

a = np.random.choice(2, size=(rows, columns), p=[(1-0.1), 0.1]) 
df = pd.DataFrame(a, columns=[f'c{i}' for i in range(size)])

df = drop_almost_zero(df,percentage)

assert (df == 0).sum(axis='rows').max() <= percentage/100*rows
assert (df == 0).sum(axis='columns').max() <=  percentage/100*columns
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...