web-dev-qa-db-fra.com

Comment créer un DataFrame en préservant l'ordre des colonnes?

Comment créer un DataFrame à partir de plusieurs tableaux numpy, Pandas Series ou Pandas DataFrame tout en préservant l'ordre des colonnes?

Par exemple, j'ai ces deux tableaux numpy et je souhaite les combiner en tant que Pandas DataFrame.

foo = np.array( [ 1, 2, 3 ] )
bar = np.array( [ 4, 5, 6 ] )

Si je fais cela, la colonne bar viendra en premier parce que dict ne préserve pas l'ordre.

pd.DataFrame( { 'foo': pd.Series(foo), 'bar': pd.Series(bar) } )

    bar foo
0   4   1
1   5   2
2   6   3

Je peux le faire, mais cela devient fastidieux lorsque je dois combiner plusieurs variables.

pd.DataFrame( { 'foo': pd.Series(foo), 'bar': pd.Series(bar) }, columns = [ 'foo', 'bar' ] )

EDIT: Existe-t-il un moyen de spécifier les variables à associer et d'organiser l'ordre des colonnes en une seule opération? Autrement dit, cela ne me dérange pas d'utiliser plusieurs lignes pour terminer l'opération, mais je préférerais ne pas avoir à spécifier les variables à joindre plusieurs fois (étant donné que je changerai beaucoup le code et qu'il est sujet à des erreurs) .

EDIT2: Un point de plus. Si je veux ajouter ou supprimer une des variables à joindre, je veux seulement ajouter/supprimer à un endroit.

35
ceiling cat

Solution d'origine: Utilisation incorrecte de collections.OrderedDict

Dans ma solution d'origine, j'avais proposé d'utiliser OrderedDict à partir du paquetage collections dans la bibliothèque standard de python.

>>> import numpy as np
>>> import pandas as pd
>>> from collections import OrderedDict
>>>
>>> foo = np.array( [ 1, 2, 3 ] )
>>> bar = np.array( [ 4, 5, 6 ] )
>>>
>>> pd.DataFrame( OrderedDict( { 'foo': pd.Series(foo), 'bar': pd.Series(bar) } ) )

   foo  bar
0    1    4
1    2    5
2    3    6

Solution idéale: passer des paires de clés à la valeur clé pour la conservation des commandes

Toutefois, comme indiqué, si un dictionnaire normal est passé à OrderedDict, l'ordre peut toujours ne pas être conservé, car cet ordre est randomisé lors de la construction du dictionnaire. Cependant, une solution consiste à convertir une liste de paires clé-valeur Tuple en une OrderedDict, comme suggéré dans this SO post :

>>> import numpy as np
>>> import pandas as pd
>>> from collections import OrderedDict
>>>
>>> a = np.array( [ 1, 2, 3 ] )
>>> b = np.array( [ 4, 5, 6 ] )
>>> c = np.array( [ 7, 8, 9 ] )
>>>
>>> pd.DataFrame( OrderedDict( { 'a': pd.Series(a), 'b': pd.Series(b), 'c': pd.Series(c) } ) )

   a  c  b
0  1  7  4
1  2  8  5
2  3  9  6

>>> pd.DataFrame( OrderedDict( (('a', pd.Series(a)), ('b', pd.Series(b)), ('c', pd.Series(c))) ) )

   a  b  c
0  1  4  7
1  2  5  8
2  3  6  9
25
Eddo Hintoso

Utilisez le mot clé columns lors de la création de DataFrame:

pd.DataFrame({'foo': foo, 'bar': bar}, columns=['foo', 'bar'])

Notez également que vous n'avez pas besoin de créer la série.

16
blokeley

Pour préserver l’ordre des colonnes, transmettez vos tableaux numpy sous forme de liste de n-uplets à DataFrame.from_items:

>>> df = pd.DataFrame.from_items([('foo', foo), ('bar', bar)])

   foo  bar
0    1    4
1    2    5
2    3    6

Mettre à jour

From pandas 0.23 from_items est obsolète et sera supprimé. Donc passez les tableaux numpy en utilisant from_dict. Pour utiliser from_dict, vous devez transmettre les éléments sous forme de dictionnaire:

>>> from collections import OrderedDict as OrderedDict
>>> df = pd.DataFrame.from_dict(OrderedDict(Zip(['foo', 'bar'], [foo, bar])))

A partir de python 3.7, vous pouvez compter sur l'ordre d'insertion préservé (voir https://mail.python.org/pipermail/python-dev/2017-December/151283.html ) pour:

>>> df = pd.DataFrame.from_dict(dict(Zip(['foo', 'bar'], [foo, bar])))

ou simplement:

>>> df = pd.DataFrame(dict(Zip(['foo', 'bar'], [foo, bar])))
14
Vidhya G

Après avoir créé votre cadre de données, vous pouvez simplement réorganiser les colonnes comme vous le souhaitez en utilisant

df= df[['foo','bar']]
6
tfv

Je ne pourrais pas commenter, mais comment allez-vous spécifier l'ordre des colonnes (puisque vous ne pouvez pas utiliser de dictionnaire)?

Si vous souhaitez conserver un dictionnaire commandé:

from collections import OrderedDict
import numpy as np
import pandas as pd

data = OrderedDict()
data['foo'] = np.array([1, 2, 3])
data['bar'] = np.array([4, 5, 6])

df = pd.DataFrame(data)

Si vous avez juste une liste de clés pour la commande:

data = {key: value for key, value in data.iteritems()}
df = pd.concat(data.values(), keys=['foo', 'bar'], axis=1)

La réponse de @ tfv est probablement le moyen le plus concis de faire ce que vous voulez.

1
Eric
>>> pd.concat([pd.Series(eval(col), name=col) for col in ['foo', 'bar']], axis=1)
   foo  bar
0    1    4
1    2    5
2    3    6

Cela fonctionne avec eval . Votre liste de noms de colonnes doit correspondre au nom de variable correspondant.

>>> eval('foo')
array([1, 2, 3])
1
Alexander

Créez le cadre de données avec uniquement les données qu'il contient et transposez-le.

Ajoutez ensuite les colonnes.

>>> foo = np.array( [ 1, 2, 3 ] )
>>> bar = np.array( [ 4, 5, 6 ] )
>>>     
>>> df = pd.DataFrame([foo, bar]).T
>>> df.columns = ['foo','bar']
>>> df
  foo bar
0  1   4
1  2   5
2  3   6
0
Saminfeld

Une autre solution pourrait être de passer un X_ au titre de la colonne, où X est le numéro d'ordre de la colonne:

pd.DataFrame( { '2_foo': pd.Series(foo), '1_bar': pd.Series(bar) } )

Et après cela, vous pouvez utiliser des colonnes ou quelque chose pour renommer les colonnes! ... Le moins de code Pythonic au monde !!!

Bonne chance les copains!

0
Borja_042

Cela peut être une autre façon de l'aborder:

foo = np.array( [ 1, 2, 3 ] )
bar = np.array( [ 4, 5, 6 ] )
stacked = np.vstack((x,y)).T
stacked
array([[1, 4],
       [2, 5],
       [3, 6]])

new_df = pd.DataFrame(stacked, columns = ['foo', 'bar'] )
new_df
   foo  bar
0   1   4
1   2   5
2   3   6
0
Joe T. Boka

Ce que j'ai fait est comme suit:

# Creating list of dict
list_of_dicts = ({'key1':'valueA', 'key2':'valueB},{'key1':'valueC', 'key2':'valueD}')

#getting list of keys from the dict
keys_list = list(list_of_dicts.keys())

# and finally
df = pd.DataFrame(list_of_dicts, columns = keys_list)

A parfaitement fonctionné pour moi.

0
Leonardo Pmont