Tengo un marco de datos

     year month     v_0     v_1   ...      v_27    v_28    v_29    v_30
0    1919    03     0.0     0.0   ...       0.0    13.0     0.0     0.0
1    1919    04     5.0     0.0   ...       0.0     0.0     0.0 -9999.0
2    1919    05     0.0     0.0   ...       0.0     0.0     0.0     0.0

Los encabezados son año, mes y todos los días del mes. Quiero convertir los encabezados separados para cada día en una sola columna, que sería el número de día para cada mes seguido de los datos. Debería verse más o menos así.

Year         Month  Day  Value

1919           3     1    0

1919           3     2    0
2
Chinmay 15 oct. 2018 a las 20:32

2 respuestas

La mejor respuesta

Desea usar DataFrame.melt ():

Teniendo en cuenta el siguiente marco de datos df:

        Year    Month   v_1     v_2
  0     1901    2       4       8
  1     1902    3       5       9
  2     1903    4       6       10
  3     1904    5       7       11

Llamar a df.melt(id_vars=['Year', 'Month'], var_name='Day') produce este resultado:

       Year     Month   Day         value
  0     1901    2       v_1             4
  1     1902    3       v_1             5
  2     1903    4       v_1             6
  3     1904    5       v_1             7
  4     1901    2       v_2             8
  5     1902    3       v_2             9
  6     1903    4       v_2             10
  7     1904    5       v_2             11

Lo que sucede aquí es que la fusión mueve todos los datos de las columnas que no sean Año y Mes (los id_vars) a un nuevo "valor" de columna, y los nombres de columna (v_0, v_1, etc.) se convertirán en una nueva columna llamada "variable". Podemos establecer el nombre de esta nueva columna con el argumento var_name, que configuré en 'Día' arriba.

En realidad, debido a que los nombres de las columnas del día comienzan con "v_", comenzaría renombrando estas columnas:

df.rename(axis='columns', mapper=lambda s: s.split('_')[-1], inplace=True)
df.melt(id_vars=['Year', 'Month'], var_name='Day')
1
rje 15 oct. 2018 a las 17:57

Es posible que deba marcar wide_to_long

pd.wide_to_long(df,'v',i=['year','month'],j='day',sep='_').reset_index()
Out[108]: 
    year  month day       v
0   1919      3   0     0.0
1   1919      3   1     0.0
2   1919      3  27     0.0
3   1919      3  28    13.0
4   1919      3  29     0.0
5   1919      3  30     0.0
6   1919      4   0     5.0
7   1919      4   1     0.0
8   1919      4  27     0.0
9   1919      4  28     0.0
10  1919      4  29     0.0
11  1919      4  30 -9999.0
12  1919      5   0     0.0
13  1919      5   1     0.0
14  1919      5  27     0.0
15  1919      5  28     0.0
16  1919      5  29     0.0
17  1919      5  30     0.0
2
YOBEN_S 15 oct. 2018 a las 17:44