2017-10-18 8 views
-5

J'essaie de trouver un moyen de diviser un fichier CSV en multivers CSV en fonction du numéro de la première colonne (n'importe quel nombre différent pour créer un nouveau fichier CSV). Des idées pour le faire?Comment diviser CSV en CSV?

 
00015,item 1,3,5.50 
00015,item 2,3,2.50 
00015,item 3,3,1.50 
00015,item 4,3,6.50 
00015,item 5,3,8.50 
00015,item 6,3,9.50 
00555,item 1,3,5.50 
00555,item 2,3,2.50 
00555,item 3,3,1.50 
00555,item 4,3,6.50 
00555,item 5,3,8.50 
00555,item 6,3,9.50 

doit créer deux CSVs:

 
00015,item 1,3,5.50 
00015,item 2,3,2.50 
00015,item 3,3,1.50 
00015,item 4,3,6.50 
00015,item 5,3,8.50 
00015,item 6,3,9.50 
 
00555,item 1,3,5.50 
00555,item 2,3,2.50 
00555,item 3,3,1.50 
00555,item 4,3,6.50 
00555,item 5,3,8.50 
00555,item 6,3,9.50 
+0

Quelle langue vous êtes désireux d'y parvenir avec? – Leonidas199x

+1

Qu'avez-vous essayé jusqu'à présent? –

+2

assez simple si vous connaissez les bases de la façon de lire/écrire des fichiers et certaines opérations de chaînes ... lire d'abord CSV, diviser en 2 tableaux en fonction du premier élément, puis écrire ces tableaux dans des fichiers séparés –

Répondre

2

Assez facile à PowerShell dans votre cas au moins:

  1. Lire le fichier sous forme de texte (pas analyser CSV):

    Get-Content foo.csv | 
    
  2. Groupe par le premier numéro (l'extrait suivant peut gérer valide CSV, de sorte que même quelques lignes citées ne sont pas un problème):

    Group-Object { $_ -replace ',.*' -replace '"' } | 
    
  3. Ecrire dans des fichiers différents:

    ForEach-Object { 
        $_.Group | Out-File ($_.Name + ".csv") 
    } 
    

Tout mettre ensemble:

Get-Content foo.csv | 
Group-Object { $_ -replace ',.*' -replace '"' } | 
ForEach-Object { 
    $_.Group | Out-File ($_.Name + ".csv") 
} 

Cette approche fonctionne même pour les fichiers où les sections avec les mêmes numéros ne sont pas adjacentes.

+0

Jeton inattendu '',. * '' Dans l'expression ou la déclaration. – dimitris

+1

devrait être un '-replace' au lieu de' .replace' il – TessellatingHeckler

+0

Fonctionne bien pour moi quand il est exécuté en tant que one-liner: 'Get-Content C: \ dossier \ fichier.csv | Group-Object {$ _ -replace ',. *' -replace '"'} | ForEach-Object {$ _. Groupe | Out-File ($ _. Nom +" .csv ")}' –

0

en C# vous pouvez utiliser GroupBy pour faire

foreach(var csv in File.ReadLines(path) 
         .Select(l => l.Split(',')) 
         .GroupBy(l => l[0])) 
{ 
    var newpath = Path.Combine(Path.GetDirectoryName(path), 
           Path.GetFileNameWithoutExtension(path) + $"_{csv.Key}.csv") 
    File.WriteAllLines(newpath, csv); 
} 
0

S'il est possible que les valeurs de la colonne 1 ne soient pas contiguës dans le fichier, l'approche suivante garantit que toutes les entrées sont écrites ensemble. Le nom de fichier de chaque fichier CSV est basé sur la valeur de la colonne 1:

from collections import defaultdict 
import csv 

data = defaultdict(list) 

with open('input.csv', 'rb') as f_input: 
    csv_input = csv.reader(f_input) 
    header = next(csv_input) 

    for row in csv_input: 
     data[row[0].strip()].append(row) 

for title, entries in data.items(): 
    with open("{}.csv".format(title), 'wb') as f_output: 
     csv_output = csv.writer(f_output) 
     csv_output.writerow(header) 
     csv_output.writerows(entries) 

Cela fonctionnera sur Python 2.x. Si le fichier ne contient pas d'en-tête, supprimez les deux lignes liées à l'en-tête. Actuellement, il copiera un en-tête du fichier CSV principal dans tous les fichiers CSV secondaires.

0

vous pouvez utiliser Pandas: Solution la plus pythonique :)

import pandas pd 
data = pd.read_csv('filename', sep=',', header=None) 
frame = pd.DataFrame(data) 
for i, x in enumerate(frame.groupby(frame[0])): 
    x[1].to_csv(open('{}.csv'.format(i),'w'), header=False,sep=',')