Création d'un Pandas DataFrame à partir d'un tableau Numpy: Comment spécifier la colonne d'index et les en-têtes de colonne?


281

J'ai un tableau Numpy composé d'une liste de listes, représentant un tableau à deux dimensions avec des étiquettes de ligne et des noms de colonne comme indiqué ci-dessous:

data = array([['','Col1','Col2'],['Row1',1,2],['Row2',3,4]])

J'aimerais que le DataFrame résultant ait Row1 et Row2 comme valeurs d'index, et Col1, Col2 comme valeurs d'en-tête

Je peux spécifier l'index comme suit:

df = pd.DataFrame(data,index=data[:,0]),

cependant, je ne sais pas comment attribuer au mieux les en-têtes de colonne.


3
La réponse de @ behzad.nouri est correcte, mais je pense que vous devriez considérer si vous ne pouvez pas avoir les données initiales sous une autre forme. Parce que maintenant, vos valeurs seront des chaînes et non des entiers (en raison du tableau numpy mélangeant les entrées et les chaînes, donc toutes sont converties en chaîne car les tableaux numpy doivent être homogènes).
joris

Réponses:


316

Vous devez spécifier data, indexet columnsau DataFrameconstructeur, comme dans:

>>> pd.DataFrame(data=data[1:,1:],    # values
...              index=data[1:,0],    # 1st column as index
...              columns=data[0,1:])  # 1st row as the column names

modifier : comme dans le commentaire @joris, vous devrez peut-être modifier ci-dessus np.int_(data[1:,1:])pour avoir le type de données correct.


7
cela fonctionne - mais pour une telle structure commune de données d'entrée et d'application souhaitée à un DataFramepas de "raccourci"? C'est essentiellement la façon dont les csvs sont chargés - et peut être géré par la gestion par défaut de nombreux lecteurs csv. Une structure analogue pour les df serait utile.
javadba

J'ai ajouté une mini méthode d'aide / de commodité pour cela comme réponse supplémentaire.
javadba

94

Voici une solution facile à comprendre

import numpy as np
import pandas as pd

# Creating a 2 dimensional numpy array
>>> data = np.array([[5.8, 2.8], [6.0, 2.2]])
>>> print(data)
>>> data
array([[5.8, 2.8],
       [6. , 2.2]])

# Creating pandas dataframe from numpy array
>>> dataset = pd.DataFrame({'Column1': data[:, 0], 'Column2': data[:, 1]})
>>> print(dataset)
   Column1  Column2
0      5.8      2.8
1      6.0      2.2

20
Mais vous avez dû spécifier manuellement les Seriesnoms .. ce n'est pas évolutif.
javadba

24

Je suis d'accord avec Joris; il semble que vous devriez faire cela différemment, comme avec les tableaux d'enregistrement numpy . En modifiant "l'option 2" de cette excellente réponse , vous pouvez le faire comme ceci:

import pandas
import numpy

dtype = [('Col1','int32'), ('Col2','float32'), ('Col3','float32')]
values = numpy.zeros(20, dtype=dtype)
index = ['Row'+str(i) for i in range(1, len(values)+1)]

df = pandas.DataFrame(values, index=index)

13

Cela peut être fait simplement en utilisant from_records of pandas DataFrame

import numpy as np
import pandas as pd
# Creating a numpy array
x = np.arange(1,10,1).reshape(-1,1)
dataframe = pd.DataFrame.from_records(x)

Cette réponse ne fonctionne pas avec les données d'exemple fournies dans la question, c'est-à-dire data = array([['','Col1','Col2'],['Row1',1,2],['Row2',3,4]]).
jpp

La solution générale la plus simple lorsque nous n'avons pas spécifié les étiquettes.
cerebrou

12
    >>import pandas as pd
    >>import numpy as np
    >>data.shape
    (480,193)
    >>type(data)
    numpy.ndarray
    >>df=pd.DataFrame(data=data[0:,0:],
    ...        index=[i for i in range(data.shape[0])],
    ...        columns=['f'+str(i) for i in range(data.shape[1])])
    >>df.head()
    [![array to dataframe][1]][1]

entrez la description de l'image ici


8

Ajout à la réponse de @ behzad.nouri - nous pouvons créer une routine d'aide pour gérer ce scénario courant:

def csvDf(dat,**kwargs): 
  from numpy import array
  data = array(dat)
  if data is None or len(data)==0 or len(data[0])==0:
    return None
  else:
    return pd.DataFrame(data[1:,1:],index=data[1:,0],columns=data[0,1:],**kwargs)

Essayons-le:

data = [['','a','b','c'],['row1','row1cola','row1colb','row1colc'],
     ['row2','row2cola','row2colb','row2colc'],['row3','row3cola','row3colb','row3colc']]
csvDf(data)

In [61]: csvDf(data)
Out[61]:
             a         b         c
row1  row1cola  row1colb  row1colc
row2  row2cola  row2colb  row2colc
row3  row3cola  row3colb  row3colc

0

Je pense que c'est une méthode simple et intuitive:

data = np.array([[0, 0], [0, 1] , [1, 0] , [1, 1]])
reward = np.array([1,0,1,0])

dataset = pd.DataFrame()
dataset['StateAttributes'] = data.tolist()
dataset['reward'] = reward.tolist()

dataset

Retour:

entrez la description de l'image ici

Mais il y a des implications de performances détaillées ici:

Comment définir la valeur d'une colonne pandas comme liste


0

Ce n'est pas si court, mais peut peut-être vous aider.

Création d'un tableau

import numpy as np
import pandas as pd

data = np.array([['col1', 'col2'], [4.8, 2.8], [7.0, 1.2]])

>>> data
array([['col1', 'col2'],
       ['4.8', '2.8'],
       ['7.0', '1.2']], dtype='<U4')

Création d'un bloc de données

df = pd.DataFrame(i for i in data).transpose()
df.drop(0, axis=1, inplace=True)
df.columns = data[0]
df

>>> df
  col1 col2
0  4.8  7.0
1  2.8  1.2
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.