J'essaie de créer un cadre de données vide avec un index et de spécifier les types de colonne. La façon dont je le fais est la suivante:
df = pd.DataFrame(index=['pbp'],columns=['contract',
'state_and_county_code',
'state',
'county',
'starting_membership',
'starting_raw_raf',
'enrollment_trend',
'projected_membership',
'projected_raf'],
dtype=['str', 'str', 'str', 'str', 'int', 'float', 'float', 'int', 'float'])
Cependant, j'obtiens l'erreur suivante,
TypeError: data type not understood
Qu'est-ce que ça veut dire?
Cela sent vraiment comme un insecte.
Voici une autre solution (plus simple).
import pandas as pd
import numpy as np
def df_empty(columns, dtypes, index=None):
assert len(columns)==len(dtypes)
df = pd.DataFrame(index=index)
for c,d in Zip(columns, dtypes):
df[c] = pd.Series(dtype=d)
return df
df = df_empty(['a', 'b'], dtypes=[np.int64, np.int64])
print(list(df.dtypes)) # int64, int64
Juste une remarque.
Vous pouvez contourner l'erreur de type en utilisant np.dtype
:
pd.DataFrame(index = ['pbp'], columns = ['a','b'], dtype = np.dtype([('str','float')]))
mais vous obtenez à la place:
NotImplementedError: compound dtypes are not implementedin the DataFrame constructor
J'ai trouvé cette question après avoir rencontré le même problème. Je préfère la solution suivante (Python 3) pour créer un DataFrame vide avec no index.
import numpy as np
import pandas as pd
def make_empty_typed_df(dtype):
tdict = np.typeDict
types = Tuple(tdict.get(t, t) for (_, t, *__) in dtype)
if any(t == np.void for t in types):
raise NotImplementedError('Not Implemented for columns of type "void"')
return pd.DataFrame.from_records(np.array([Tuple(t() for t in types)], dtype=dtype)).iloc[:0, :]
Tester cela ...
from itertools import chain
dtype = [('col%d' % i, t) for i, t in enumerate(chain(np.typeDict, set(np.typeDict.values())))]
dtype = [(c, t) for (c, t) in dtype if (np.typeDict.get(t, t) != np.void) and not isinstance(t, int)]
print(make_empty_typed_df(dtype))
En dehors:
Empty DataFrame
Columns: [col0, col6, col16, col23, col24, col25, col26, col27, col29, col30, col31, col32, col33, col34, col35, col36, col37, col38, col39, col40, col41, col42, col43, col44, col45, col46, col47, col48, col49, col50, col51, col52, col53, col54, col55, col56, col57, col58, col60, col61, col62, col63, col64, col65, col66, col67, col68, col69, col70, col71, col72, col73, col74, col75, col76, col77, col78, col79, col80, col81, col82, col83, col84, col85, col86, col87, col88, col89, col90, col91, col92, col93, col95, col96, col97, col98, col99, col100, col101, col102, col103, col104, col105, col106, col107, col108, col109, col110, col111, col112, col113, col114, col115, col117, col119, col120, col121, col122, col123, col124, ...]
Index: []
[0 rows x 146 columns]
Et les types de données ...
print(make_empty_typed_df(dtype).dtypes)
En dehors:
col0 timedelta64[ns]
col6 uint16
col16 uint64
col23 int8
col24 timedelta64[ns]
col25 bool
col26 complex64
col27 int64
col29 float64
col30 int8
col31 float16
col32 uint64
col33 uint8
col34 object
col35 complex128
col36 int64
col37 int16
col38 int32
col39 int32
col40 float16
col41 object
col42 uint64
col43 object
col44 int16
col45 object
col46 int64
col47 int16
col48 uint32
col49 object
col50 uint64
...
col144 int32
col145 bool
col146 float64
col147 datetime64[ns]
col148 object
col149 object
col150 complex128
col151 timedelta64[ns]
col152 int32
col153 uint8
col154 float64
col156 int64
col157 uint32
col158 object
col159 int8
col160 int32
col161 uint64
col162 int16
col163 uint32
col164 object
col165 datetime64[ns]
col166 float32
col167 bool
col168 float64
col169 complex128
col170 float16
col171 object
col172 uint16
col173 complex64
col174 complex128
dtype: object
L'ajout d'un index est délicat, car la plupart des types de données ne contiennent pas de véritable valeur manquante. Ils sont donc convertis en un autre type avec une valeur manquante native (par exemple, int
s est converti en float
s ou object
s) données des types que vous avez spécifiés, vous pouvez toujours insérer des lignes si nécessaire, et vos types seront respectés. Ceci peut être accompli avec:
df.loc[index, :] = new_row
Encore une fois, comme l'a souligné @Hun, ce n'est PAS la manière dont les pandas sont destinés à être utilisés.
Vous pouvez faire cela en passant un dictionnaire dans le constructeur DataFrame:
df = pd.DataFrame(index=['pbp'],
data={'contract' : np.full(1, "", dtype=str),
'starting_membership' : np.full(1, np.nan, dtype=float),
'projected_membership' : np.full(1, np.nan, dtype=int)
}
)
Cela vous donnera correctement un cadre de données ressemblant à:
contract projected_membership starting_membership
pbp "" NaN -9223372036854775808
Avec dtypes:
contract object
projected_membership float64
starting_membership int64
Cela dit, il y a deux choses à noter:
1) str
n'est pas réellement un type qu'une colonne DataFrame peut gérer; au lieu de cela, il revient au cas général object
. Cela fonctionnera toujours correctement.
2) Pourquoi ne voyez-vous pas NaN
sous starting_membership
? NaN
n'est défini que pour les flottants; il n'y a pas de valeur "Aucune" pour les nombres entiers. Il transforme donc np.NaN
en un nombre entier. Si vous souhaitez une valeur par défaut différente, vous pouvez la modifier dans l'appel np.full
.
les pandas n'offrent pas la colonne entière pure. Vous pouvez soit utiliser la colonne float et convertir cette colonne en entier si nécessaire ou la traiter comme un objet. Ce que vous essayez de mettre en œuvre n’est pas la façon dont les pandas sont censés être utilisés. Mais si vous le souhaitez VRAIMENT, vous pouvez contourner le message TypeError en procédant ainsi.
df1 = pd.DataFrame(index=['pbp'], columns=['str1','str2','str2'], dtype=str)
df2 = pd.DataFrame(index=['pbp'], columns=['int1','int2'], dtype=int)
df3 = pd.DataFrame(index=['pbp'], columns=['flt1','flt2'], dtype=float)
df = pd.concat([df1, df2, df3], axis=1)
str1 str2 str2 int1 int2 flt1 flt2
pbp NaN NaN NaN NaN NaN NaN NaN
Vous pouvez réorganiser l'ordre des cols à votre guise. Mais encore une fois, ce n’est pas ainsi que les pandas étaient censés être utilisés.
df.dtypes
str1 object
str2 object
str2 object
int1 object
int2 object
flt1 float64
flt2 float64
dtype: object
Notez que int est traité comme un objet.
C'est une vieille question, mais je ne vois pas de réponse solide (même si @eric_g était très proche).
Il vous suffit de créer un cadre de données vide avec une liste de paires clé/dictionnaire: La clé est votre nom de colonne et la valeur est un type de données vide.
Ainsi, dans votre exemple de jeu de données, cela ressemblerait à ceci:
df = pd.DataFrame(,columns=[{'contract':'',
'state_and_county_code':'',
'state':'',
'county':'',
'starting_membership':int(),
'starting_raw_raf':float(),
'enrollment_trend':float(),
'projected_membership':int(),
'projected_raf':float(),
'pbp':int() #just guessing on this data type
}]).set_index=("pbp")
Tu peux le faire comme ça
import numpy
import pandas
dtypes = numpy.dtype([
('a', str),
('b', int),
('c', float),
('d', numpy.datetime64),
])
data = numpy.empty(0, dtype=dtypes)
df = pandas.DataFrame(data)