La construction de pandas DataFrame à partir de valeurs dans des variables donne «ValueError: si vous utilisez toutes les valeurs scalaires, vous devez passer un index»

370

Cela peut être une question simple, mais je ne sais pas comment faire cela. Disons que j'ai deux variables comme suit.

a = 2
b = 3

Je veux construire un DataFrame à partir de ceci:

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

Cela génère une erreur:

ValueError: si vous utilisez toutes les valeurs scalaires, vous devez passer un index

J'ai aussi essayé ça:

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

Cela donne le même message d'erreur.

Nilani Algiriyage
la source

Réponses:

572

Le message d'erreur indique que si vous passez des valeurs scalaires, vous devez passer un index. Vous ne pouvez donc pas utiliser de valeurs scalaires pour les colonnes - par exemple, utilisez une liste:

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

ou utilisez des valeurs scalaires et passez un index:

>>> df = pd.DataFrame({'A': a, 'B': b}, index=[0])
>>> df
   A  B
0  2  3
DSM
la source
7
C'est peut-être parce que l'ordre des éléments dans une liste en Python est persistant alors que l'ordre des éléments dans un dictionnaire ne l'est pas. Vous pouvez instancier un DataFrame avec un dictionnaire vide. En principe, je suppose qu'un DataFrame à une seule ligne, comme illustré ici, serait également correct à construire à partir d'un dictionnaire, car l'ordre n'a pas d'importance (mais cela n'a pas été implémenté). Cependant, avec plusieurs lignes, Pandas ne serait pas en mesure de créer un DataFrame car il ne saurait pas quels éléments appartenaient à la même ligne.
Alexander
2
@VitalyIsaev - Dans ce cas, la ligne de trame de données (représentée par le dictionnaire donné) n'a pas d'index (même pas implicite). Une solution simple consiste à envelopper le dictionnaire dans une liste, qui a une "indexation naturelle". On peut affirmer que si un seul dictionnaire est donné (sans liste de synthèse), alors supposer index=0, mais cela peut conduire à une mauvaise utilisation accidentelle (en pensant qu'un seul dictionnaire peut en quelque sorte créer une trame de données à plusieurs lignes)
Ori
plusieurs solutions dans ce lien eulertech.wordpress.com/2017/11/28/…
Jason Goal
La raison en est que les DataFrames sont censés contenir des données bidimensionnelles (c'est-à-dire des rangées de deux variables OP). Si vous souhaitez simplement conserver les paires index -> valeurs (comme un dictionnaire), vous devez utiliser une série, comme le suggère Rob .
danuker
Il s'agit d'un Dataframe échantillon / ligne unique, donc index = [0] est logique; mais vous pouvez également le manipuler pour qu'il soit index = [100], ce qui fonctionne. Q: Index n'est-il pas censé être logiquement incrémenté, pourquoi python permet-il la manipulation d'index?
Sumanth Lazarus
65

Vous pouvez également utiliser pd.DataFrame.from_recordsce qui est plus pratique lorsque vous avez déjà le dictionnaire en main:

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

Vous pouvez également définir l'index, si vous le souhaitez, en:

df = pd.DataFrame.from_records([{ 'A':a,'B':b }], index='A')
fax
la source
27
Cette réponse ne fonctionne pas pour moi - je reçois le même message d'erreur lors de l'utilisation de from_records.
Dave Kielpinski
Dave, avez-vous essayé le morceau de code (définissez a et b, bien sûr)? Recevez-vous toujours un message d'erreur? Pouvez-vous poster?
fAX
12
@DaveKielpinski Avez-vous peut-être oublié d'ajouter les crochets?
Dennis
Cela utilisera les touches dict comme noms de colonne. Comment définir les clés pour indexer?
mingchau
@DaveKielpinski Veuillez vérifier si vous avez transmis une liste à la méthode "from_records"; sinon, cela ne fonctionnera pas et vous obtiendrez le même message d'erreur que lorsque vous appelez DataFrame sur le dictionnaire.
mairan
55

Vous devez d'abord créer une série de pandas. La deuxième étape consiste à convertir la série pandas en trame de données pandas.

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

Vous pouvez même fournir un nom de colonne.

pd.Series(data).to_frame('ColumnName')
MLguy
la source
1
Cela a fonctionné pour moi. Mon dictionnaire avait des clés entières et des valeurs ndarray.
StatsSorceress
pd.Series(data).to_frame('ColumnName')est plus court, bien que cet équivalent soit peut-être plus direct:pd.DataFrame.from_dict(data, orient='index', columns=['ColumnName'])
Alex F
29

Vous pouvez essayer d’envelopper votre dictionnaire dans la liste

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

pd.DataFrame([my_dict])

   A  B
0  1  2
Débutant
la source
8

Peut-être que Series fournirait toutes les fonctions dont vous avez besoin:

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

DataFrame peut être considéré comme une collection de séries, vous pouvez donc:

  • Concaténer plusieurs séries en une seule trame de données (comme décrit ici )

  • Ajouter une variable série dans un bloc de données existant ( exemple ici )

Rob
la source
7

Vous devez fournir des itérables comme valeurs pour les colonnes Pandas DataFrame:

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

J'ai eu le même problème avec les tableaux numpy et la solution est de les aplatir:

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

df = pd.DataFrame(data)
MicheleDIncecco
la source
3

Si vous avez l'intention de convertir un dictionnaire de scalaires, vous devez inclure un index:

import pandas as pd

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

Bien que l'index ne soit pas requis pour un dictionnaire de listes, la même idée peut être étendue à un dictionnaire de listes:

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)

Bien sûr, pour le dictionnaire de listes, vous pouvez construire le dataframe sans index:

planets_df = pd.DataFrame(planets)
print(planets_df)
k0L1081
la source
3

Tu pourrais essayer:

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

De la documentation sur l'argument 'orient': Si les clés du dict passé doivent être les colonnes du DataFrame résultant, passez 'colonnes' (par défaut). Sinon, si les clés doivent être des lignes, passez 'index'.

Matthew Connell
la source
Veuillez utiliser des outils de mise en forme pour éditer et formater correctement votre question / réponse. Les codes dans les phrases doivent être formatés en code mots très importants à mettre en gras , en caractères moins importants Italique Utilisez également des listes si nécessaire
Morse
Cela ne résout pas la question posée, cela produit un résultat différent de celui souhaité.
Ken Williams
3

La magie des pandas au travail. Toute logique est sortie.

Le message d'erreur "ValueError: If using all scalar values, you must pass an index"Dit que vous devez passer un index.

Cela ne signifie pas nécessairement que la réussite d'un indice oblige les pandas à faire ce que vous voulez qu'il fasse

Lorsque vous passez un index, les pandas traitent vos clés de dictionnaire comme des noms de colonne et les valeurs comme ce que la colonne doit contenir pour chacune des valeurs de l'index.

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

    A   B
1   2   3

Passer un index plus grand:

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

Un index est généralement généré automatiquement par une trame de données quand aucun n'est donné. Cependant, les pandas ne savent pas combien de lignes 2et 3vous voulez. Vous pouvez cependant être plus explicite à ce sujet

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

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

L'index par défaut est basé sur 0 cependant.

Je recommanderais toujours de passer un dictionnaire de listes au constructeur de trames de données lors de la création de trames de données. C'est plus facile à lire pour les autres développeurs. Les pandas ont beaucoup de mises en garde, ne faites pas en sorte que d'autres développeurs aient des experts dans chacun d'eux pour lire votre code.

firelynx
la source
3

l'entrée ne doit pas nécessairement être une liste d'enregistrements - il peut également s'agir d'un seul dictionnaire:

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

Ce qui semble être équivalent à:

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

En effet, un DataFrame a deux dimensions intuitives - les colonnes et les lignes.

Vous spécifiez uniquement les colonnes à l'aide des clés de dictionnaire.

Si vous ne souhaitez spécifier que des données unidimensionnelles, utilisez une série!

danuker
la source
0

Convertir le dictionnaire en trame de données

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

Donner un nouveau nom à la colonne

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

Si vous avez un dictionnaire, vous pouvez le transformer en un bloc de données pandas avec la ligne de code suivante:

pd.DataFrame({"key": d.keys(), "value": d.values()})
ingrid
la source
Cela fonctionne, mais à mon humble avis, cela n'a pas beaucoup de sens <code> `<! - language: 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: valeur clé 0 (bananes, pommes) (21, 10) 1 (bananes, pommes) (21, 10) <code>
Emiter
-3

Passez le dict sur une liste:

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