Tengo la siguiente lista:
list = [-0.14626096918979603,
0.017925919395027533,
0.41265398151061766]
He creado un pandas
dataframe
usando el siguiente código:
df = pd.DataFrame(list, index=['var1','var2','var3'], columns=['Col1'])
df
Col1
var1 -0.146261
var2 0.017926
var3 0.412654
Ahora tengo una nueva lista:
list2 = [-0.14626096918979603,
0.017925919395027533,
0.41265398151061766,
-0.8538301985671065,
0.08182534201640915,
0.40291331836021105]
Me gustaría organizar el dataframe
de manera que la salida se vea así (EDICIÓN MANUAL)
Col1 Col2
var1 -0.146261 -0.8538301985671065
var2 0.017926 0.08182534201640915
var3 0.412654 0.40291331836021105
Y que siempre que haya una tercera columna o foruth ... los datos se organizan de la misma manera. Intenté convertir la lista a dict
pero como soy nuevo en Python no obtengo el resultado deseado, sino solo errores debido a formas no válidas.
-- EDITAR --
Una vez que haya creado el marco de datos, quiero trazarlo usando df.plot()
. Sin embargo, la forma en que se muestran los datos no es lo que me gustaría. Vengo de R
, así que no estoy seguro de si esto se debe a la estructura de datos utilizada en dataframe
. ¿Es que necesito una medida en cada fila?
Mi idea sería tener col1
, col2
, col3
en el eje x (es una serie temporal). En el eje y, el rango de valores (de modo que está bien en ese gráfico) y las líneas denet diferentes deberían mostrar la evolución de var1
, var2
, var3
, etc.
4 respuestas
Podrías correr algo como
df = pd.DataFrame(index = ['var1', 'var2', 'var3'])
n_cols = int(np.ceil(len(list2) / len(df)))
for ii in range(n_cols):
L = list2[ii * len(df) : (ii + 1) * len(df)]
df['col_{}'.format(ii)] = L
Si la longitud de su lista no es múltiplo de la longitud del marco de datos (len(list2) % len(df) != 0
, debe extender L (en el último bucle) con los valores de NaN len(df) - (len(list2) % len(df))
Para responder la segunda pregunta, debería ser suficiente para ejecutar
df.T.plot()
Para la tercera pregunta, se trata de cómo se diseñó originalmente el marco de datos. Puede editar el código que escribimos al principio para invertir filas y columnas
df = pd.DataFrame(columns = ['var1', 'var2', 'var3'])
n_rows = int(np.ceil(len(list2) / len(df.columns)))
for ii in range(n_rows):
L = list2[ii * len(df.columns) : (ii + 1) * len(df.columns)]
df.loc['col_{}'.format(ii)] = L
Pero una vez que creó el marco de datos con la primera forma diseñada, no hay nada de malo en ejecutar
df = df.T
Solución simple
>>> pd.DataFrame({ 'a': list1, 'b': list2 })
a b
0 -0.146261 -0.146261
1 0.017926 0.017926
2 0.412654 0.412654
>>>
Nota: Asegúrese de igualar el número de elementos en la lista1 y la lista2.
Esto es lo que se me ocurrió. Puede generalizarlo fácilmente a más columnas / filas configurando dinámicamente la forma
import numpy as np
import pandas as pd
np_list = np.array(list2)
list_prep = np.transpose(np_list.reshape(2, 3))
df = pd.DataFrame(list_prep, index=['v1', 'v2', 'v3'], columns=['c1', 'c2'])
Y el resultado final se ve así:
c1 c2
v1 -0.146261 -0.853830
v2 0.017926 0.081825
v3 0.412654 0.402913
Para nombrar automáticamente las columnas en función del número de columnas que se crearán, podría:
from numpy import array
from pandas import DataFrame
rows = 3
cols = int(len(list2) / rows)
data = DataFrame(array(list2).reshape(cols, rows).T)
data.columns = ['Col{}'.format(i + 1) for i in range(cols)]
data.index = ['var{}'.format(i + 1) for i in range(rows)]
Salida:
Col1 Col2
var1 -0.146261 -0.853830
var2 0.017926 0.081825
var3 0.412654 0.402913
Esto implica menos codificación del número de columnas / nombres de columnas.
Su pregunta editada sobre el trazado es algo completamente diferente, pero aquí va de todos modos:
import matplotlib.pyplot as plt
plt.plot(data.columns, data.T)
plt.legend(data.index)
plt.show()
Su gráfico debería verse mejor ya que tiene más datos, pero los datos de ejemplo solo tenían dos columnas: