web-dev-qa-db-fra.com

Création d'un Pandas DataFrame avec un tableau numpy contenant plusieurs types

Je veux créer un pandas dataframe avec des valeurs par défaut de zéro, mais une colonne d'entiers et l'autre de flottants. Je suis capable de créer un tableau numpy avec les types corrects, voir le values variable ci-dessous. Cependant, lorsque je passe cela dans le constructeur dataframe, il ne renvoie que des valeurs NaN (voir df ci-dessous). J'ai inclus le code non typé qui renvoie un tableau de flottants (voir df2)

import pandas as pd
import numpy as np

values = np.zeros((2,3), dtype='int32,float32')
index = ['x', 'y']
columns = ['a','b','c']

df = pd.DataFrame(data=values, index=index, columns=columns)
df.values.dtype

values2 = np.zeros((2,3))
df2 = pd.DataFrame(data=values2, index=index, columns=columns)
df2.values.dtype

Des suggestions sur la façon de construire la trame de données?

15
bfcondon

Voici quelques options parmi lesquelles vous pouvez choisir:

import numpy as np
import pandas as pd

index = ['x', 'y']
columns = ['a','b','c']

# Option 1: Set the column names in the structured array's dtype 
dtype = [('a','int32'), ('b','float32'), ('c','float32')]
values = np.zeros(2, dtype=dtype)
df = pd.DataFrame(values, index=index)

# Option 2: Alter the structured array's column names after it has been created
values = np.zeros(2, dtype='int32, float32, float32')
values.dtype.names = columns
df2 = pd.DataFrame(values, index=index, columns=columns)

# Option 3: Alter the DataFrame's column names after it has been created
values = np.zeros(2, dtype='int32, float32, float32')
df3 = pd.DataFrame(values, index=index)
df3.columns = columns

# Option 4: Use a dict of arrays, each of the right dtype:
df4 = pd.DataFrame(
    {'a': np.zeros(2, dtype='int32'),
     'b': np.zeros(2, dtype='float32'),
     'c': np.zeros(2, dtype='float32')}, index=index, columns=columns)

# Option 5: Concatenate DataFrames of the simple dtypes:
df5 = pd.concat([
    pd.DataFrame(np.zeros((2,), dtype='int32'), columns=['a']), 
    pd.DataFrame(np.zeros((2,2), dtype='float32'), columns=['b','c'])], axis=1)

# Option 6: Alter the dtypes after the DataFrame has been formed. (This is not very efficient)
values2 = np.zeros((2, 3))
df6 = pd.DataFrame(values2, index=index, columns=columns)
for col, dtype in Zip(df6.columns, 'int32 float32 float32'.split()):
    df6[col] = df6[col].astype(dtype)

Chacune des options ci-dessus produit le même résultat

   a  b  c
x  0  0  0
y  0  0  0

avec dtypes:

a      int32
b    float32
c    float32
dtype: object

Pourquoi pd.DataFrame(values, index=index, columns=columns) produit un DataFrame avec NaNs:

values est un tableau structuré avec des noms de colonne f0, f1, f2:

In [171]:  values
Out[172]: 
array([(0, 0.0, 0.0), (0, 0.0, 0.0)], 
      dtype=[('f0', '<i4'), ('f1', '<f4'), ('f2', '<f4')])

Si vous passez l'argument columns=['a', 'b', 'c'] À pd.DataFrame, Alors Pandas recherchera les colonnes portant ces noms dans le tableau structuré values. Lorsque celles-ci les colonnes sont introuvables, Pandas place NaNs dans le DataFrame pour représenter les valeurs manquantes.

39
unutbu