У меня есть набор данных РНК-секвенирования с одной ячейкой, который я хочу нормализовать, однако из-за его размера (> 1 000 000 ячеек, ~ 23 000 генов) использование Python с Pandas просто недостаточно эффективно (даже при оптимизации типов данных, разделении данных на части) и 128 ГБ оперативной памяти в моем распоряжении).
Поэтому я хочу запустить этот шаг нормализации в AWK (или других методах, которые были бы полезны), пропуская подход с интенсивным использованием памяти Pandas. Концептуально набор данных представляет собой файл TSV с генами в виде строк и ячеек в виде столбцов. Размер составляет ~ 130 ГБ, при тестировании на подмножестве ~ 1 ГБ потребуется около 6 ГБ ОЗУ в Pandas. Невозможно выполнить нормализацию для всего набора данных, но нормализация, скажем, 100 разделов, все еще является очень неэффективным методом.
Это пример (с примерами данных) того, как должна происходить нормализация, которую я успешно применил к меньшим подмножествам:
# determine dtypes and downcast to reduce memory usage
tmp_count_data = pd.read_csv(file_path, sep="\t", index_col=0, nrows=100)
tmp_float_cols = [c for c in tmp_count_data if tmp_count_data[c].dtype == "float64"]
tmp_float32_cols = {c: np.float32 for c in tmp_float_cols}
count_data = pd.read_csv(file_path, sep="\t", index_col=0, engine="c", dtype=tmp_float32_cols)
>>> count_data
c1 c2
-
GeneA 0.0 0.0
GeneB 1.0 0.0
GeneC 6.0 3.0
GeneD 4.0 3.0
def normalize(df):
# load dataframe values
dge = df.values
# calculate column sums
col_sums = np.apply_along_axis(sum,0,dge)
# divide cell value by column sum, multiply by 10000, add 1, apply natural logarithm
mat_dge_norm = np.log( dge/[float(x) for x in col_sums] * 10000 + 1 )
# add column and row names back to dataframe
df_dge_norm = pd.DataFrame(mat_dge_norm,index=df.index,columns=df.columns)
# return dataframe
return df_dge_norm
Нормализация должна идти следующим образом:
- разделить ячейку k в столбце C на сумму столбца C
- разделите это на 10000
- добавить 1 к этому
- принять натуральный логарифм результата