tablas renombrar para nombres nombre leer funciones datos columnas columna cambiar python pandas

para - renombrar columnas dataframe python



Python Pandas: cómo aplanar un índice jerárquico en columnas (10)

Creo que la forma más fácil de hacerlo sería establecer las columnas en el nivel superior:

df.columns = df.columns.get_level_values(0)

Nota: si el nivel tiene un nombre, también puede acceder a él por este, en lugar de por 0.

.

Si desea combinar / join su MultiIndex en un índice (suponiendo que solo tiene entradas de cadenas en sus columnas) , puede:

df.columns = ['' ''.join(col).strip() for col in df.columns.values]

Nota: debemos strip el espacio en blanco para cuando no haya un segundo índice.

In [11]: ['' ''.join(col).strip() for col in df.columns.values] Out[11]: [''USAF'', ''WBAN'', ''day'', ''month'', ''s_CD sum'', ''s_CL sum'', ''s_CNT sum'', ''s_PC sum'', ''tempf amax'', ''tempf amin'', ''year'']

Tengo un marco de datos con un índice jerárquico en el eje 1 (columnas) (de una operación groupby.agg):

USAF WBAN year month day s_PC s_CL s_CD s_CNT tempf sum sum sum sum amax amin 0 702730 26451 1993 1 1 1 0 12 13 30.92 24.98 1 702730 26451 1993 1 2 0 0 13 13 32.00 24.98 2 702730 26451 1993 1 3 1 10 2 13 23.00 6.98 3 702730 26451 1993 1 4 1 0 12 13 10.04 3.92 4 702730 26451 1993 1 5 3 0 10 13 19.94 10.94

Quiero aplanarlo para que se vea así (los nombres no son críticos, podría cambiar el nombre):

USAF WBAN year month day s_PC s_CL s_CD s_CNT tempf_amax tmpf_amin 0 702730 26451 1993 1 1 1 0 12 13 30.92 24.98 1 702730 26451 1993 1 2 0 0 13 13 32.00 24.98 2 702730 26451 1993 1 3 1 10 2 13 23.00 6.98 3 702730 26451 1993 1 4 1 0 12 13 10.04 3.92 4 702730 26451 1993 1 5 3 0 10 13 19.94 10.94

¿Cómo hago esto? (He intentado mucho, fue en vano).

Por una sugerencia, aquí está la cabeza en forma dict

{(''USAF'', ''''): {0: ''702730'', 1: ''702730'', 2: ''702730'', 3: ''702730'', 4: ''702730''}, (''WBAN'', ''''): {0: ''26451'', 1: ''26451'', 2: ''26451'', 3: ''26451'', 4: ''26451''}, (''day'', ''''): {0: 1, 1: 2, 2: 3, 3: 4, 4: 5}, (''month'', ''''): {0: 1, 1: 1, 2: 1, 3: 1, 4: 1}, (''s_CD'', ''sum''): {0: 12.0, 1: 13.0, 2: 2.0, 3: 12.0, 4: 10.0}, (''s_CL'', ''sum''): {0: 0.0, 1: 0.0, 2: 10.0, 3: 0.0, 4: 0.0}, (''s_CNT'', ''sum''): {0: 13.0, 1: 13.0, 2: 13.0, 3: 13.0, 4: 13.0}, (''s_PC'', ''sum''): {0: 1.0, 1: 0.0, 2: 1.0, 3: 1.0, 4: 3.0}, (''tempf'', ''amax''): {0: 30.920000000000002, 1: 32.0, 2: 23.0, 3: 10.039999999999999, 4: 19.939999999999998}, (''tempf'', ''amin''): {0: 24.98, 1: 24.98, 2: 6.9799999999999969, 3: 3.9199999999999982, 4: 10.940000000000001}, (''year'', ''''): {0: 1993, 1: 1993, 2: 1993, 3: 1993, 4: 1993}}


En caso de que desee tener un separador en el nombre entre niveles, esta función funciona bien.

def flattenHierarchicalCol(col,sep = ''_''): if not type(col) is tuple: return col else: new_col = '''' for leveli,level in enumerate(col): if not level == '''': if not leveli == 0: new_col += sep new_col += level return new_col df.columns = df.columns.map(flattenHierarchicalCol)


La respuesta de Andy Hayden es ciertamente la manera más fácil: si quieres evitar las etiquetas de columnas duplicadas, necesitas ajustar un poco

In [34]: df Out[34]: USAF WBAN day month s_CD s_CL s_CNT s_PC tempf year sum sum sum sum amax amin 0 702730 26451 1 1 12 0 13 1 30.92 24.98 1993 1 702730 26451 2 1 13 0 13 0 32.00 24.98 1993 2 702730 26451 3 1 2 10 13 1 23.00 6.98 1993 3 702730 26451 4 1 12 0 13 1 10.04 3.92 1993 4 702730 26451 5 1 10 0 13 3 19.94 10.94 1993 In [35]: mi = df.columns In [36]: mi Out[36]: MultiIndex [(USAF, ), (WBAN, ), (day, ), (month, ), (s_CD, sum), (s_CL, sum), (s_CNT, sum), (s_PC, sum), (tempf, amax), (tempf, amin), (year, )] In [37]: mi.tolist() Out[37]: [(''USAF'', ''''), (''WBAN'', ''''), (''day'', ''''), (''month'', ''''), (''s_CD'', ''sum''), (''s_CL'', ''sum''), (''s_CNT'', ''sum''), (''s_PC'', ''sum''), (''tempf'', ''amax''), (''tempf'', ''amin''), (''year'', '''')] In [38]: ind = pd.Index([e[0] + e[1] for e in mi.tolist()]) In [39]: ind Out[39]: Index([USAF, WBAN, day, month, s_CDsum, s_CLsum, s_CNTsum, s_PCsum, tempfamax, tempfamin, year], dtype=object) In [40]: df.columns = ind In [46]: df Out[46]:       USAF   WBAN  day  month  s_CDsum  s_CLsum  s_CNTsum  s_PCsum  tempfamax  tempfamin  / 0  702730  26451    1      1       12        0        13        1      30.92      24.98    1  702730  26451    2      1       13        0        13        0      32.00      24.98    2  702730  26451    3      1        2       10        13        1      23.00       6.98    3  702730  26451    4      1       12        0        13        1      10.04       3.92    4  702730  26451    5      1       10        0        13        3      19.94      10.94       year   0  1993   1  1993   2  1993   3  1993   4  1993


Siguiendo @jxstanford y @ tvt173, escribí una función rápida que debería hacer el truco, independientemente de los nombres de columna string / int:

def flatten_cols(df): df.columns = [ ''_''.join(tuple(map(str, t))).rstrip(''_'') for t in df.columns.values ] return df


También podría hacer lo siguiente. Considere df para ser su marco de datos y asuma un índice de dos niveles (como es el caso en su ejemplo)

df.columns = [(df.columns[i][0])+''_''+(datadf_pos4.columns[i][1]) for i in range(len(df.columns))]


Un poco tarde quizás, pero si no te preocupan los nombres de columna duplicados:

df.columns = df.columns.tolist()


Una solución general que maneja múltiples niveles y tipos mixtos:

df.columns = [''_''.join(tuple(map(str, t))) for t in df.columns.values]


Y si desea retener cualquier información de agregación del segundo nivel del multiindex, puede intentar esto:

In [1]: new_cols = [''''.join(t) for t in df.columns] Out[1]: [''USAF'', ''WBAN'', ''day'', ''month'', ''s_CDsum'', ''s_CLsum'', ''s_CNTsum'', ''s_PCsum'', ''tempfamax'', ''tempfamin'', ''year''] In [2]: df.columns = new_cols


df.columns = [''_''.join(tup).rstrip(''_'') for tup in df.columns.values]


pd.DataFrame(df.to_records()) # multiindex become columns and new index is integers only