J'ai quelques valeurs est le fichier csv et dans le fichier csv, certaines valeurs sont numériques et certaines sont le nombre de chaînes. Exemple de fichier csv:
1,"1151226468812.22",100,1,467,999.00,999.95,15,1,999.00,999.95,998.50,999.95,15,999.01,1396,34,06092016091501.444,1394627.25
2,"1151226468812.11",100,1,467,999.00,1000.00,1605,3,999.00,1000.00,998.50,1000.00,5,999.03,1426,37,06092016091502.111,1424626.50
J'ai donc voulu convertir une chaîne en float. Alors voici mon code:
datareader = csv.reader(datafile, delimiter=",", quoting= csv.QUOTE_NONE)
names = []
names.append("local_timestamp")
names.append("nse_timestamp")
for row in datareader:
data = dict()
data.update(local_timestamp = row[0])
data.update(nse_timestamp = float(row[1]))
Mais cela renvoie une erreur de valeur.
ValueError: could not convert string to float: '"1151226468812.22"'
Le problème est que votre chaîne n'est pas simplement '1151226468812.22'
, mais '"1151226468812.22"'
. Il contient également des marques de parole ("
). Cela signifie qu'avant de convertir cela en float, vous devez supprimer les marques vocales de début et de fin. Heureusement, Python a une méthode de chaîne très pratique .strip()
pour le faire à votre place.
string.strip(s)
retournera une chaîne dont les caractères 's'
début et fin ont été supprimés
Par exemple:
myString = "#hello#".strip("#")
Dans ce code, myString
serait juste 'hello'
Dans ce cas, vous souhaitez effacer row[1]
des caractères "
début et fin. Vous pouvez le faire très facilement:
row[1].strip("\"")
Le deuxième champ de votre csv est cité avec "
. Dans CSV, avoir des champs entre guillemets ne signifie pas que ce sont des chaînes, mais que le champ pourrait contenir un délimiteur, tel que "123,45"
.
La bonne façon de lire ces données est de dire au lecteur que certains champs peuvent être cités:
datareader = csv.reader(datafile, delimiter=',', quotechar='"')
Cela renverra le deuxième champ sans les guillemets et résoudra votre problème.
La suppression ultérieure des guillemets ajoute non seulement du travail supplémentaire, mais peut également entraîner des erreurs si le champ contient un délimiteur. Par exemple, "123,45"
renverrait "123
et 45"
sous deux champs différents.
Il est évident que le problème réside dans les guillemets doubles, Python ne pouvant convertir qu'une chaîne de nombres (et le symbole décimal) en un nombre à virgule flottante.
Une façon de supprimer les guillemets doubles consiste à utiliser une expression régulière. Cela vous permet d'exécuter le même code, que l'entrée comporte des guillemets ou non:
import re
print(float(re.split(r'[\"]?([0-9\.]*)[\"]?','1151226468812.22')[1]))
print(float(re.split(r'[\"]?([0-9\.]*)[\"]?','"1151226468812.22"')[1]))
Les sorties:
1151226468812.22
1151226468812.22
Cette expression régulière correspondra à:
[\"]?
un double guillemet de départ, si présent (?
en prend soin).[0-9\.]*
une série de nombres ou caractères de points de longueur arbitray (*
prend soin de cette dernière).[\"]?
une fin de citation double, si présente.Il retourne une liste de longueur trois, dont le deuxième élément contient le numéro. Ceci peut alors être converti en float.
Essayez d'utiliser ce qui suit:
for row in datareader:
data = dict()
data.update(local_timestamp = row[0])
data.update(nse_timestamp = float(row[1].replace('"', '')))
ou
for row in datareader:
data = dict()
data.update(local_timestamp = row[0])
data.update(nse_timestamp = float(row[1].strip('"')))
Cela supprimera les guillemets doubles et vous pouvez maintenant convertir la chaîne en float.