La construcción de pandas DataFrame a partir de valores en variables proporciona "ValueError: si usa todos los valores escalares, debe pasar un índice"

370

Esta puede ser una pregunta simple, pero no puedo entender cómo hacerlo. Digamos que tengo dos variables de la siguiente manera.

a = 2
b = 3

Quiero construir un DataFrame a partir de esto:

df2 = pd.DataFrame({'A':a,'B':b})

Esto genera un error:

ValueError: si usa todos los valores escalares, debe pasar un índice

Intenté esto también:

df2 = (pd.DataFrame({'a':a,'b':b})).reset_index()

Esto da el mismo mensaje de error.

Nilani Algiriyage
fuente

Respuestas:

572

El mensaje de error dice que si está pasando valores escalares, debe pasar un índice. Por lo tanto, no puede usar valores escalares para las columnas; por ejemplo, use una lista

>>> df = pd.DataFrame({'A': [a], 'B': [b]})
>>> df
   A  B
0  2  3

o use valores escalares y pase un índice:

>>> df = pd.DataFrame({'A': a, 'B': b}, index=[0])
>>> df
   A  B
0  2  3
DSM
fuente
77
Quizás sea porque el orden de los elementos en una lista en Python es persistente, mientras que el orden de los elementos en un diccionario no lo es. Puede crear una instancia de un DataFrame con un diccionario vacío. En principio, supongo que un DataFrame de una sola fila, como se muestra aquí, también estaría bien construir desde un diccionario porque el orden no importa (pero esto no se ha implementado). Sin embargo, con varias filas, Pandas no podría hacer un DataFrame porque no sabría qué elementos pertenecían a la misma fila.
Alexander
2
@VitalyIsaev: en ese caso, la fila del marco de datos (representada por el diccionario dado) no tiene índice (ni siquiera uno implícito). Una solución simple es ajustar el diccionario dentro de una lista, que tiene "indexación natural". Uno puede afirmar que si solo se da un diccionario (sin una lista de ajuste), entonces asuma index=0, pero eso puede conducir a un mal uso accidental (pensar que un solo diccionario de alguna manera puede crear un marco de datos de varias filas)
Ori
varias soluciones en este enlace eulertech.wordpress.com/2017/11/28/…
Jason Goal
La razón de esto es porque los DataFrames están destinados a contener datos bidimensionales (es decir, filas de las dos variables de OP). Si solo desea mantener pares de índice -> valor (como un Diccionario), entonces debe usar una Serie, como sugiere Rob .
danuker
Este es un único Dataframe de muestra / fila, por lo que index = [0] tiene sentido lógico; pero también podría manipularlo para que sea index = [100], lo que funciona. P: ¿No se supone que Index está ordenado lógicamente de forma incremental, por qué Python permite la manipulación de Index?
Sumanth Lazarus el
65

También puede usar pd.DataFrame.from_recordscuál es más conveniente cuando ya tiene el diccionario en la mano:

df = pd.DataFrame.from_records([{ 'A':a,'B':b }])

También puede establecer el índice, si lo desea, por:

df = pd.DataFrame.from_records([{ 'A':a,'B':b }], index='A')
fax
fuente
27
Esta respuesta no me funciona: recibo el mismo mensaje de error cuando uso from_records.
Dave Kielpinski
Dave, ¿probaste el código (define ayb, por supuesto)? ¿Todavía recibes un mensaje de error? ¿Puedes publicar?
fAX
12
@DaveKielpinski ¿Quizás olvidaste agregar los corchetes?
Dennis
Esto usará las teclas dict como nombres de columna. ¿Cómo configurar las claves para indexar?
mingchau
@DaveKielpinski Por favor, verifique si pasó una lista al método "from_records"; de lo contrario, no funcionará y obtendrá el mismo mensaje de error que cuando llama a DataFrame en el diccionario.
mairan
55

Primero debes crear una serie de pandas. El segundo paso es convertir la serie de pandas en un marco de datos de pandas.

import pandas as pd
data = {'a': 1, 'b': 2}
pd.Series(data).to_frame()

Incluso puede proporcionar un nombre de columna.

pd.Series(data).to_frame('ColumnName')
MLguy
fuente
1
Esto funcionó para mí. Mi diccionario tenía claves enteras y valores ndarray.
StatsSorceress
pd.Series(data).to_frame('ColumnName')es más corto, aunque este equivalente es quizás más directo:pd.DataFrame.from_dict(data, orient='index', columns=['ColumnName'])
Alex F
29

Puede intentar ajustar su diccionario a la lista

my_dict = {'A':1,'B':2}

pd.DataFrame([my_dict])

   A  B
0  1  2
NewBie
fuente
8

Quizás Series le proporcionaría todas las funciones que necesita:

pd.Series({'A':a,'B':b})

DataFrame puede considerarse como una colección de Series, por lo tanto, puede:

  • Concatene múltiples series en un marco de datos (como se describe aquí )

  • Agregue una variable de serie en el marco de datos existente ( ejemplo aquí )

Robar
fuente
7

Debe proporcionar iterables como los valores para las columnas Pandas DataFrame:

df2 = pd.DataFrame({'A':[a],'B':[b]})
ely
fuente
6

Tuve el mismo problema con las matrices numpy y la solución es aplanarlas:

data = {
    'b': array1.flatten(),
    'a': array2.flatten(),
}

df = pd.DataFrame(data)
MicheleDIncecco
fuente
3

Si tiene la intención de convertir un diccionario de escalares, debe incluir un índice:

import pandas as pd

alphabets = {'A': 'a', 'B': 'b'}
index = [0]
alphabets_df = pd.DataFrame(alphabets, index=index)
print(alphabets_df)

Aunque el índice no es necesario para un diccionario de listas, la misma idea se puede ampliar a un diccionario de listas:

planets = {'planet': ['earth', 'mars', 'jupiter'], 'length_of_day': ['1', '1.03', '0.414']}
index = [0, 1, 2]
planets_df = pd.DataFrame(planets, index=index)
print(planets_df)

Por supuesto, para el diccionario de listas, puede construir el marco de datos sin un índice:

planets_df = pd.DataFrame(planets)
print(planets_df)
k0L1081
fuente
3

Tu podrías intentar:

df2 = pd.DataFrame.from_dict({'a':a,'b':b}, orient = 'index')

De la documentación sobre el argumento 'orientar': si las claves del dict aprobado deben ser las columnas del DataFrame resultante, pase 'columnas' (predeterminado). De lo contrario, si las claves deben ser filas, pase 'index'.

Matthew Connell
fuente
Utilice las herramientas de formato para editar y formatear correctamente su pregunta / respuesta. Códigos dentro de las oraciones deben ser formateados como code palabras muy importante estar en negrita , onces menos importantes cursiva utilizar también las listas si es necesario
Morse
Esto no resuelve la pregunta formulada, produce un resultado diferente al deseado.
Ken Williams
3

Pandas mágicos en el trabajo. Toda la lógica está fuera.

El mensaje de error "ValueError: If using all scalar values, you must pass an index"dice que debe pasar un índice.

Esto no significa necesariamente que pasar un índice haga que los pandas hagan lo que quieres que haga

Cuando pasa un índice, los pandas tratarán las claves del diccionario como nombres de columna y los valores como lo que debe contener la columna para cada uno de los valores del índice.

a = 2
b = 3
df2 = pd.DataFrame({'A':a,'B':b}, index=[1])

    A   B
1   2   3

Pasando un índice más grande:

df2 = pd.DataFrame({'A':a,'B':b}, index=[1, 2, 3, 4])

    A   B
1   2   3
2   2   3
3   2   3
4   2   3

Por lo general, un marco de datos genera automáticamente un índice cuando no se proporciona ninguno. Sin embargo, los pandas no saben cuántas filas de 2y 3qué quieres. Sin embargo, puedes ser más explícito al respecto

df2 = pd.DataFrame({'A':[a]*4,'B':[b]*4})
df2

    A   B
0   2   3
1   2   3
2   2   3
3   2   3

Sin embargo, el índice predeterminado está basado en 0.

Siempre recomendaría pasar un diccionario de listas al constructor del marco de datos al crear marcos de datos. Es más fácil de leer para otros desarrolladores. Pandas tiene muchas advertencias, no hagas que otros desarrolladores tengan que tener expertos en todas ellas para leer tu código.

firelynx
fuente
3

la entrada no tiene que ser una lista de registros; también puede ser un diccionario único:

pd.DataFrame.from_records({'a':1,'b':2}, index=[0])
   a  b
0  1  2

Lo que parece ser equivalente a:

pd.DataFrame({'a':1,'b':2}, index=[0])
   a  b
0  1  2
SV
fuente
2

Esto se debe a que un DataFrame tiene dos dimensiones intuitivas: las columnas y las filas.

Solo está especificando las columnas con las teclas del diccionario.

Si solo desea especificar datos unidimensionales, ¡use una Serie!

danuker
fuente
0

Convertir diccionario a marco de datos

col_dict_df = pd.Series(col_dict).to_frame('new_col').reset_index()

Dar un nuevo nombre a la columna

col_dict_df.columns = ['col1', 'col2']
kamran kausar
fuente
-2

Si tiene un diccionario, puede convertirlo en un marco de datos de pandas con la siguiente línea de código:

pd.DataFrame({"key": d.keys(), "value": d.values()})
ingrid
fuente
Funciona, pero en mi humilde opinión, no tiene mucho sentido <code> `<! - idioma: lang-py -> fruits_count = defaultdict (int) fruits_count [" apples "] = 10 fruits_count [" bananas "] = 21 pd.DataFrame ({"key": fruits_count.keys (), "value": fruits_count.values ​​()}) Out: valor clave 0 (bananas, manzanas) (21, 10) 1 (bananas, manzanas) (21, 10) <code>
Emiter
-3

Simplemente pase el dict en una lista:

a = 2
b = 3
df2 = pd.DataFrame([{'A':a,'B':b}])
LeandroHumb
fuente