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.

user3132783
la source
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.

behzad.nouri
la source
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
Jagannath Banerjee
la source
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)
ryanjdillon
la source
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)
Aadil Srivastava
la source
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

Rahul Verma
la source
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
javadba
la source
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

ciel bleu
la source
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
Rafa
la source