web-dev-qa-db-fra.com

Pandas Modification du format des valeurs NaN lors de l'enregistrement au format CSV

Je travaille avec un df et j'utilise numpy pour transformer les données - y compris en définissant des blancs (ou '') en NaN. Mais quand j'écris le df en csv - la sortie contient la chaîne 'nan' comme opposée à NULL.

J'ai regardé autour de moi mais je ne trouve pas de solution viable. Voici le problème de base:

df
index x    y   z
0     1   NaN  2
1     NaN  3   4

Sortie CSV:

index x    y   z
0     1   nan  2
1     nan  3   4

J'ai essayé quelques choses pour mettre 'nan' à NULL mais la sortie csv donne un 'vide' plutôt que NULL:

dfDemographics = dfDemographics.replace('nan', np.NaN)
dfDemographics.replace(r'\s+( +\.)|#', np.nan, regex=True).replace('', 
np.nan)
dfDemographics = dfDemographics.replace('nan', '')  # of course, this wouldn't work, but tried it anyway.

Toute aide serait appréciée.

10
Jerry

Pandas à la rescousse, utilisez na_rep pour fixer votre propre représentation des NaN.

df.to_csv('file.csv', na_rep='NULL')

file.csv

,index,x,y,z
0,0,1.0,NULL,2
1,1,NULL,3.0,4
18
cs95

L'utilisateur @coldspeed illustre comment remplacer les valeurs nan avec NULL lors de l'enregistrement de pd.DataFrame. Dans le cas, pour l'analyse des données, on est intéressé à remplacer les valeurs "NULL" dans pd.DataFrame par des valeurs np.NaN, le code suivant fera l'affaire:

import numpy as np, pandas as pd

# replace NULL values with np.nan
colNames = mydf.columns.tolist()
dfVals = mydf.values
matSyb = mydf.isnull().values
dfVals[matSyb] = np.NAN

mydf = pd.DataFrame(dfVals, columns=colNames)    
#np.nansum(mydf.values, axis=0 )
#np.nansum(dfVals, axis=0 )
0
Good Will

Dans ma situation, le coupable était np.where. Lorsque les types de données des deux éléments de retour sont différents, votre np.NaN sera converti en nan.

Il est difficile (pour moi) de voir exactement ce qui se passe sous le capot, mais je soupçonne que cela pourrait être vrai pour d'autres méthodes de tableau Numpy qui ont des types mixtes.

Un exemple minimal:

import numpy as np
import pandas as pd

seq = [1, 2, 3, 4, np.NaN]
same_type_seq = np.where("parrot"=="dead", 0, seq)
diff_type_seq = np.where("parrot"=="dead", "spam", seq)

pd.Series(seq).to_csv("Vanilla_nan.csv", header=False) # as expected, last row is blank
pd.Series(same_type_seq).to_csv("samey_nan.csv", header=False) # also, blank
pd.Series(diff_type_seq).to_csv("nany_nan.csv", header=False) # nan instead of blank

Alors, comment contourner cela? Je ne suis pas trop sûr, mais comme solution de contournement hacky pour les petits ensembles de données, vous pouvez remplacer NaN dans votre séquence d'origine par une chaîne de jeton, puis la replacer dans np.NaN

repl = "missing"
hacky_seq = np.where("parrot"=="dead", "spam", [repl if np.isnan(x) else x for x in seq])
pd.Series(hacky_seq).replace({repl:np.NaN}).to_csv("hacky_nan.csv", header=False)
0
gherka

L'utilisation de df.replace peut aider -

df = df.replace(np.nan, '', regex=True)
df.to_csv("df.csv", index=False)

(Cela définit toutes les valeurs nulles sur '', c'est-à-dire une chaîne vide.)

0
Kranthi Kiran