Je voudrais tous mes dataframes, qu'ils soient construits à partir de l'une des surcharges de constructeur, qu'ils soient dérivés de .read_csv()
, .read_xlsx()
, .read_sql()
, ou toute autre méthode, pour utiliser le nouveau nullable Int64
type de données comme valeur par défaut dtype
pour tous les entiers, plutôt que int64
.
Je suis prêt à aller littéralement à n'importe quel niveau de folie pour le faire s'il n'y a pas de méthode `` sympa '', y compris le sous-classement des classes DataFrame ou Series, et la réimplémentation d'un certain nombre de méthodes et d'attributs de constructeur, etc.
Ma question est, cela peut-il être fait? Si oui, comment pourrais-je procéder?
Je mettrais mon argent pour patcher des singes. Le moyen le plus simple serait de patcher le constructeur du DataFrame. Cela devrait ressembler à ceci:
import pandas
pandas.DataFrame.__old__init__ = pandas.DataFrame.__init__
def new_init(self, data=None, index=None, columns=None, dtype=pd.Int64Dtype(), copy=False):
self.__old__init__(data=data, index=index, columns=None, dtype=dtype, copy=copy)
pandas.DataFrame.__init__ = new_init
Bien sûr, vous courez le risque de briser le monde. Bonne chance!
Vous pouvez utiliser une fonction comme celle-ci:
def nan_ints(df,convert_strings=False,subset = None):
types = ['int64','float64']
if subset is None:
subset = list(df)
if convert_strings:
types.append('object')
for col in subset:
try:
if df[col].dtype in types:
df[col] = df[col].astype(float).astype('Int64')
except:
pass
return df
Il parcourt chaque colonne et le recouvre en Int64 s'il s'agit d'un int. S'il s'agit d'un flottant, il ne se convertira en Int64 que si toutes les valeurs de la colonne peuvent être converties en entiers autres que les NaN. Je vous ai également donné la possibilité de convertir des chaînes en Int64 avec l'argument convert_strings .
df1 = pd.DataFrame({'a':[1.1,2,3,1],
'b':[1,2,3,np.nan],
'c':['1','2','3',np.nan],
'd':[3,2,1,np.nan]})
nan_ints(df1,convert_strings=True,subset=['b','c'])
df1.info()
Renvoie ce qui suit:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 4 columns):
a 4 non-null float64
b 3 non-null Int64
c 3 non-null Int64
d 3 non-null float64
dtypes: Int64(2), float64(2)
memory usage: 216.0 bytes
si vous comptez l'utiliser sur chaque DataFrame, vous pouvez ajouter la fonction à un module et l'importer à chaque fois que vous souhaitez utiliser des pandas. from my_module import nan_ints
Ensuite, utilisez-le simplement avec quelque chose comme: nan_ints(pd.read_csv(path))
Remarque: Le type de données entier nul est Nouveau dans la version 0.24.0. Voici le documentation .