Tengo una tabla de datos de datos para una variedad de posiciones genómicas. Las posiciones se representan como tuplas de 3 ('cromosoma', 'srand', posición) que he convertido en un índice múltiple. Mi objetivo es buscar información diversa sobre cada posición y agregarla a la tabla (por ejemplo, el nombre del gen, etc.). Puedo hacer esto con pybedtools.
df = pd.DataFrame(data={'A':range(1,8), 'B':range(1,8), 'C': range(1,8)}, index=pd.MultiIndex.from_tuples([('chrom1', '-', 1234), ('chrom1', '+', 5678), ('chrom1', '+', 9876), ('chrom2', '+', 13579), ('chrom2', '+', 8497), ('chrom2', '-', 98765), ('chrom2', '-', 76856)])) df.index.rename(['chrom','strand','abs_pos'], inplace=True) ABC chrom strand abs_pos chrom1 - 1234 1 1 1 + 5678 2 2 2 9876 3 3 3 chrom2 + 13579 4 4 4 8497 5 5 5 - 98765 6 6 6 76856 7 7 7Mi problema es agregar columnas a un marco de datos con un índice múltiple. Esto parece sencillo sin un índice múltiple: pandas: agregue una nueva columna al marco de datos del diccionario
Tengo un diccionario de la información de búsqueda con claves de 3 tuplas correspondientes al índice múltiple. ¿Cómo puedo agregar estos datos como una nueva columna?
gene_d = {('chrom1', '-', 1234) : 'geneA', ('chrom1', '+', 5678): 'geneB', ('chrom1', '+', 9876): 'geneC', ('chrom2', '+', 13579): 'geneD', ('chrom2', '+', 8497): 'geneE', ('chrom2', '-', 98765): 'geneF', ('chrom2', '-', 76856): 'geneG'}Probé el mapa, pero parece que no puedo averiguar cómo hacer que funcione con un índice múltiple para obtener lo siguiente:
ABC chrom strand abs_pos gene chrom1 - 1234 geneA 1 1 1 + 5678 geneB 2 2 2 9876 geneC 3 3 3 chrom2 + 13579 geneD 4 4 4 8497 geneE 5 5 5 - 98765 geneF 6 6 6 76856 geneG 7 7 7Un enfoque vectorizado:
df['gene'] = df.index #you get the index as tuple df['gene'] = df['gene'].map(gene_d) df = df.set_index('gene', append=True)gl resultante:
ABC chrom strand abs_pos gene chrom1 - 1234 geneA 1 1 1 + 5678 geneB 2 2 2 9876 geneC 3 3 3 chrom2 + 13579 geneD 4 4 4 8497 geneE 5 5 5 - 98765 geneF 6 6 6 76856 geneG 7 7 7Convierta gene_d en un marco de datos:
df1 = pd.DataFrame.from_dict(gene_d, orient='index').rename(columns={0:'gene'})Dale un multiíndice:
df1.index = pd.MultiIndex.from_tuples(df1.index)Concatenar con df original:
new_df = pd.concat([df, df1], axis=1).sort_values('A')Haz algo de limpieza:
new_df.index.rename(['chrom','strand','abs_pos'], inplace=True) new_df.set_index('gene', append=True) new_df ABC chrom strand abs_pos gene chrom1 - 1234 geneA 1 1 1 + 5678 geneB 2 2 2 9876 geneC 3 3 3 chrom2 + 13579 geneD 4 4 4 8497 geneE 5 5 5 - 98765 geneF 6 6 6 76856 geneG 7 7 7Un enfoque no vectorizado, pero quizás útil para las personas que realmente están luchando con esto.
En mi ejemplo, tengo un df llamado bb_df, que tiene un índice múltiple con [cliente, meses] como estructura, cada sitio tiene varios meses debajo. El índice múltiple está estructurado como (niveles = [nivel_1, nivel_2], etiquetas = [nivel_1, nivel_2]). Como tal, puede obtener una lista completa de los niveles del nivel 2, en orden, para el mapeo mediante la siguiente lista de comprensión:
[bb_df.index.levels[1][x] for x in bb_df.index.labels[1]]Espero que esto ayude a alguien.