2009-12-08 8 views
1

J'ai quelques lignes dans un fichier CSV comme ceci:articles reformater intérieur liste de lecture à partir du fichier CSV en Python

10000,Account Name,0,0,"3,711.32",0,0,"18,629.64","22,340.96",COD,"20,000.00",Some string,Some string 2 

Si vous remarquez, certains numéros sont enfermés dans « » et a un séparateur de milliers " ". Je souhaite supprimer le séparateur de milliers et l'encadrement de double guillemet. Pour l'enceinte qoute, je pense à utiliser string.replace() mais qu'en est-il de la virgule à l'intérieur des guillemets?

Quelle est la meilleure façon de faire cela en Python?

Répondre

2

Vous pouvez simplement analyser le fichier CSV, apporter les modifications nécessaires, puis le réécrire.

(je n'ai pas testé ce code, mais il devrait être quelque chose comme ça)

import csv 
reader = csv.reader(open('IN.csv', 'r')) 
writer = csv.writer(open('OUT.csv', 'w') 
for row in reader: 
# do stuff to the row here 
# row is just a list of items 
writer.writerow(row) 
+1

Je ne peux pas commenter l'autre poste, mais si vous remplacez tous les virgules, vous aussi détruire tous les CSV les virgules et ce ne sera plus un fichier CSV. –

+0

Certainement le chemin à parcourir. Utilisez le module csv dans la bibliothèque standard. – thebat

+0

@Dumb Guy, c'est pourquoi je voulais supprimer les virgules à l'intérieur des guillemets et pas ailleurs. Merci pour le conseil! – Francis

1

Si tout ce que vous voulez est de supprimer les guillemets doubles et des virgules d'une chaîne, deux remplace le fera:

s = s.replace('"','').replace(',','') 

une façon plus rapide est d'utiliser s.translate, mais qui nécessite un minimum de préparation:

import string 
identity = string.maketrans('', '') 

... 

s = s.translate(identity, '",') 

Cela supprime toute occurrence de guillemets ou de virgules, et le fait aussi très vite. En général, la méthode des objets chaîne .translate est le meilleur moyen de supprimer certains types de caractères d'une chaîne (ainsi que d'effectuer éventuellement une conversion de caractère à caractère, mais en utilisant une table de traduction telle que la table identity ici, la partie traduction peut en effet être facilement contournée). Notez que .translate fonctionne un peu différemment pour les objets Unicode (et donc aussi pour les chaînes Python 3) - Je donne l'approche qui convient pour les objets Python 2 simples.

+0

Mais cela supprimerait également l'apparition des virgules en dehors des guillemets, non? – Francis

+0

@Francis, oui, il supprime toutes les virgules dans un champ (utilisez le module 'csv' pour analyser la ligne dans les champs - la suppression des virgules de champs individuels est une étape de suivi). –

2

est ici un peu d'expression régulière tripoter qui fera l'affaire:

>>> import re 
>>> p = re.compile('["]([^"]*)["]') 
>>> x = """10000,Account Name,0,0,"3,711.32",0,0,"18,629.64","22,340.96",COD,"20,000.00",Some string,Some string 2""" 
>>> p.sub(lambda m: m.groups()[0].replace(',',''), x) 
'10000,Account Name,0,0,3711.32,0,0,18629.64,22340.96,COD,20000.00,Some string,Some string 2' 

Supprime les virgules des parties de la chaîne qui est entre des paires de citations.

1

Voici quelque chose que je viens de tester, vous n'avez peut-être pas besoin de pprint, je veux juste utiliser pour effacer la sortie.

test.csv

10000,Account Name,0,0,"3,711.32",0,0,"18,629.64","22,340.96",COD,"20,000.00",Some string,Some string 2 
10000,Account Name,0,0,"3,711.32",0,0,"18,629.64","22,340.96",COD,"20,000.00",Some string,Some string 2 
code

, utilisez un lecteur de csv et passer chaque élément à fonction parseNum pour vérifier chiffres valides ou non.

from pprint import pprint 
import csv 

def parseNum(x): 
    xx=x.replace(",","") 
    if not xx.replace(".","").isdigit(): return x 
    return "." in xx and float(xx) or int(xx) 

x=[map(parseNum,line) for line in csv.reader(open("test.csv"))] 

pprint(x) 

Sortie

[[10000, 
    'Account Name', 
    0, 
    0, 
    3711.3200000000002, 
    0, 
    0, 
    18629.639999999999, 
    22340.959999999999, 
    'COD', 
    20000.0, 
    'Some string', 
    'Some string 2'], 
[10000, 
    'Account Name', 
    0, 
    0, 
    3711.3200000000002, 
    0, 
    0, 
    18629.639999999999, 
    22340.959999999999, 
    'COD', 
    20000.0, 
    'Some string', 
    'Some string 2']] 

Note: Si vous avez besoin d'une bonne précision sur le nombre de flotteur, remplacer flotteur avec Decimal

1

Utilisez le module csv. Il a toutes sortes de constantes et de paramètres pour vous aider à définir les délimiteurs, les guillemets et tout le reste pour le type de fichier avec lequel vous travaillez. Il a même un renifleur qui peut vous aider à identifier le format csv du fichier. En fait, c'est le seul module que j'ai trouvé qui peut fonctionner correctement et facilement avec des fichiers CSV.

http://docs.python.org/library/csv.html

1

Vous devez absolument utiliser le module csv. Si vous utilisez un csv.reader, vous n'avez qu'un très petit problème: tester les champs pour voir s'ils sont des nombres et enlever les virgules s'ils le sont. Je l'ai empaqueté comme un générateur:

import csv 

def read_and_fix_numbers(f): 
    """Iterate over a file object that returns CSV data, stripping commas out of numbers.""" 
    for row in csv.reader(f): 
     for field in row: 
      try: 
       x = float(field) 
       field.replace(",", "") 
      except ValueError: 
       pass 
      fixed.append(field) 
     yield fixed 

Utilisation:

>>> data = '10000,Account Name,0,0,"3,711.32",0,0,"18,629.64","22,340.96",COD,"20,000.00",Some string,Some string 2' 
>>> import StringIO 
>>> f = StringIO.StringIO(data) 
>>> for row in read_and_fix_numbers(f): 
     print row 
['10000', 'Account Name', '0', '0', '3711.32', '0', '0', '18629.64', '22340.96', 'COD', '20000.00', 'Some string', 'Some string 2'] 
Questions connexes