web-dev-qa-db-fra.com

Modification des chaînes en Flottants dans un fichier .csv importé

Question rapide pour un problème que je n'ai pas réussi à résoudre rapidement:

Je travaille avec un fichier .csv et n'arrive pas à trouver un moyen simple de convertir des chaînes en fichiers flottants. Voici mon code,

import csv

def readLines():
    with open('testdata.csv', 'rU') as data:
        reader = csv.reader(data)
        row = list(reader)
        for x in row:
            for y in x:
                print type(float(y)),
readLines()

Comme vous pouvez le constater, le type de chaque élément y figurant dans un ensemble x de listes dans la rangée variable sera actuellement imprimé. cela produit une longue liste de "<type 'float'>". Mais cela ne change pas réellement chaque élément en float, pas plus que de définir la boucle for pour qu'elle exécute float(y) (un test de type retourne 'chaîne' pour chaque élément).

J'ai aussi essayé literal_eval, mais cela a aussi échoué. La seule façon de modifier les éléments de la liste en éléments flottants consiste à créer une nouvelle liste, avec compréhension de la liste ou manuellement, mais en perdant la mise en forme originale de chaque liste (sous forme de listes d'un nombre défini d'éléments dans une liste plus grande).

Je suppose que la question générale est vraiment "Quel est le moyen le plus facile de lire, d’organiser et de synthétiser des données au format .csv ou Excel en utilisant Python?"

Merci d’avance à ceux qui sont assez courtois et qui sont suffisamment informés pour vous aider.

7
userNaN

Vous avez raison de dire que le module CSV intégré de Python est très primitif en matière de traitement de types de données mélangés, effectue toutes ses conversions de types au moment de l'importation et dispose même d'un menu d'options très restrictif, ce qui gâchera la plupart des environnements réels. ensembles de données (entre guillemets et échappements incohérents, valeurs manquantes ou incomplètes dans les booléens et les facteurs, codage Unicode incompatible, entraînant des guillemets fantômes ou des caractères d'échappement dans les champs, des lignes incomplètes provoqueront une exception) La fixation de l’importation au format csv est l’un des nombreux avantages de pandas . Donc, votre réponse ultime est en effet de cesser d’utiliser l’importation CSV intégrée et de commencer à utiliser des pandas. Mais commençons par la réponse littérale à votre question.

Vous avez d’abord demandé"Comment convertir des chaînes en floats, lors de l’importation au format csv". La réponse à cette question est d’ouvrir la csv.reader(..., quoting=csv.QUOTE_NONNUMERIC) conformément au csv doc

csv.QUOTE_NONNUMERIC: Demande au lecteur de convertir tous les champs non cités en types float.

Cela fonctionne si tous les champs non cités (entier, float, texte, booléen, etc.) sont convertis en float, ce qui est généralement une mauvaise idée pour de nombreuses raisons (les valeurs manquantes ou NA dans les booléens ou les facteurs seront supprimés silencieusement) . De plus, il va évidemment échouer (jeter une exception) sur les champs de texte non cités. Donc, il est fragile et doit être protégé avec try..catch.

Ensuite, vous avez demandé:'Je suppose que la question générale est vraiment "Quel est le moyen le plus facile de lire, d’organiser et de synthétiser des données au format .csv ou Excel en utilisant Python?"'to pour lequel la solution de csv.read merdique doit s’ouvrir avec csv.reader(..., quoting=csv.QUOTE_NONNUMERIC)

Mais comme @geoffspear a répondu correctement _ {'La réponse à votre "question générale" peut être "Pandas", bien que ce soit un peu vague.'

10
smci

Essayez quelque chose comme ce qui suit

import csv

def read_lines():
    with open('testdata.csv', 'rU') as data:
        reader = csv.reader(data)
        for row in reader:
            yield [ float(i) for i in row ]

for i in read_lines():
    print(i)

# to get a list, instead of a generator, use
xy = list(read_lines())

En ce qui concerne le moyen le plus simple, je vous suggère alors de consulter les modules xlrd, xlwt. Personnellement, j’ai toujours du mal à utiliser tous les formats CSV.

3
Antti Haapala

Lors de la conversion de plusieurs chaînes en floats, utilisez un try/except pour intercepter les erreurs:

def conv(s):
    try:
        s=float(s)
    except ValueError:
        pass    
    return s

print [conv(s) for s in ['1.1','bls','1','nan', 'not a float']] 
# [1.1, 'bls', 1.0, nan, 'not a float']

Notez que les chaînes qui ne peuvent pas être converties sont simplement passées inchangées.

Un fichier csv IS un fichier texte, vous devriez donc utiliser une fonctionnalité similaire:

def readLines():
    def conv(s):
        try:
            s=float(s)
        except ValueError:
            pass    
        return s

    with open('testdata.csv', 'rU') as data:
        reader = csv.reader(data)
        for row in reader:
            for cell in row:
                y=conv(cell)
              # do what ever with the single float
         # OR
         # yield [conv(cell) for cell in row]  if you want to write a generator...    
2
dawg
for y in x:
                print type(float(y)),

float (y) prend la valeur de y et renvoie un float basé sur celle-ci. Il ne modifie pas y- il retourne un nouvel objet.

y = float (y)

ressemble plus à ce que vous recherchez - vous devez modifier les objets.

0
Paul Becotte