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.
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
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
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.
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])))
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']]
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.
>>> 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])
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
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!
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
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.