2
votes

Restructurer le fichier CSV avec Python

J'ai un fichier csv qui ressemble à ceci:

import csv

with open ('myfile.csv', 'rb') as filein, open ('restructured.csv', 'wb') as fileout:
  rows = list(csv.DictReader(filein, skipinitialspace=True))
  names = NOT SURE HOW TO GET THIS
  fieldnames = ['Date'] + ['{}'.format(i) for i in names]
  csvout = csv.DictWriter(fileout, fieldnames=fieldnames, extrasaction='ignore', restval='NA')
  csvout.writeheader()
  for row in rows:
    row['{}'.format(row['Name'].strip())] = row['Wage']
    csvout.writerow(row)

Je voudrais le restructurer pour qu'il ressemble à ceci:

Date      Joe    Sam    Kate
5/1/19    $100   $120   $30
5/2/19    $120   $134   $56
5/3/19    $89    $90    $231

Je ne sais pas comment l'aborder. Voici ce que j'ai commencé à écrire:

Date     Name    Wage
5/1/19   Joe     $100
5/1/19   Sam     $120
5/1/19   Kate    $30
5/2/19   Joe     $120
5/2/19   Sam     $134
5/2/19   Kate    $56
5/3/19   Joe     $89
5/3/19   Sam     $90
5/3/19   Kate    $231


8 commentaires

Les modules csv sont juste un analyseur qui produit les lignes CSV sous forme de tuples ou de dicts. Il ne transforme pas à lui seul les lignes en autre chose.


il serait plus facile d'utiliser des pandas dans ce cas


Merci. Pourriez-vous me montrer l'exemple des pandas qui fait quelque chose de similaire?


@manticora Cette vidéo peut vous aider: youtube.com/watch?v=dcqPhpY7tWk


Quel est le séparateur? list (csv.DictReader (filein, skipinitialspace = True)) renvoie-t-il ce que vous attendez?


@manticora Jetez un œil à ce lien: nikgrozev.com/2015/07/01/...


Il semble que vous souhaitiez transposer un bloc de données: pandas.pydata.org/pandas-docs/stable/reference/api/...


Utilisez-vous vraiment Python 2.x?


4 Réponses :


0
votes

Cela devrait vous mettre sur la bonne voie

data.csv

Date,Sam,Kate,Joe
5/1/19,$120,$30,$100
5/2/19,$134,$56,$120
5/3/19,$90,$231,$89
data = {}
people = set()
with open('data.csv', 'r') as f:
    for line in f.read().splitlines():
        values = line.split(',')

        if values[0] not in data:
            data[values[0]] = {}

        data[values[0]][values[1]] = values[2]
        people.add(values[1])

print('Date,' + ','.join([per for per in people]))
for date in data:
    print(f"{date},{','.join([data[date][per] for per in people])}"

output:

5/1/19,Joe,$100
5/1/19,Sam,$120
5/1/19,Kate,$30
5/2/19,Joe,$120
5/2/19,Sam,$134
5/2/19,Kate,$56
5/3/19,Joe,$89
5/3/19,Sam,$90
5/3/19,Kate,$231


1 commentaires

Je pense que OP veut enregistrer en tant que fichier CSV, pas imprimer les sorties.



2
votes

Simplement avec la bibliothèque pandas :

     Date   Joe  Kate   Sam
0  5/1/19  $100   $30  $120
1  5/2/19  $120   $56  $134
2  5/3/19   $89  $231   $90

La sortie:

import pandas as pd

df = pd.read_csv("test.csv", sep="\s+")
p_table = pd.pivot_table(df, values='Wage', columns=['Name'], index='Date', 
                         aggfunc=lambda x:x)
p_table = p_table.reset_index()
p_table.columns.name = None

print(p_table)

Liens de référence:

https: // pandas .pydata.org / pandas-docs / stable / reference / api / pandas.read_csv.html

http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.pivot_table.html p>


1 commentaires

J'aime votre fonction d'agrégation ici, je n'avais jamais vu ou pensé à cela auparavant.



2
votes

Cela peut être fait avec le module csv. Voici le chemin pour Python 3:

with open ('myfile.csv', 'rb') as filein, open ('restructured.csv', 'wb') as fileout:

Le csv généré devrait ressembler à:

Date,Kate,Joe,Sam
5/1/19,$30,$100,$120
5/2/19,$56,$120,$134
5/3/19,$231,$89,$90

Il en va de même pour Python 2 sauf pour la première ligne qui devrait être:

import csv
import collections

with open ('myfile.csv', 'r') as filein, open ('restructured.csv', 'w', newline='') as fileout:
    data = collections.defaultdict(dict)
    names = set()
    for row in csv.DictReader(filein, skipinitialspace=True):
        data[row['Date']][row['Name']] = row['Wage']
        names.add(row['Name'])
    csvout = csv.DictWriter(fileout, fieldnames = ['Date'] + list(names))
    csvout.writeheader()
    for dat in sorted(data.keys()):
        row = data[dat]
        row['Date'] = dat
        csvout.writerow(row)


3 commentaires

Cela a fonctionné pour moi - merci beaucoup! Mais les données ne sont pas triées par date: (Ma première colonne ressemble à ceci: Date 1/5/19 5/2/19 5/19/19 5/29/19 5/24/19 5/27/19 5 / 21/19 5/9/19 J'ai essayé de le trier avec des post-mots python, mais j'ai eu l'erreur suivante: ValueError: les données de temps '5' ne correspondent pas au format '% m-% d-% y'


Il peut facilement être trié par date. Voir ma modification à pour les données triées (data.keys ()):


Je pense qu'il ne la reconnaît pas comme une date car cette fois, elle l'a triée de cette façon: 1/5/19, 10/05/19, 11/05/19 et ainsi de suite



1
votes

Ce que vous voulez faire est également connu comme la conversion du format long au format large. En utilisant pandas , vous pouvez facilement le faire en

import pandas as pd

df = pd.read_csv("myfile.csv", sep = ',')

# Restructure the dataframe
tdf = df.pivot(index = 'Date', columns = 'Name', values = 'Wage')

tdf.to_csv("restructured.csv", sep = ',')

print(tdf)
Name     Joe  Kate   Sam
Date                    
5/1/19  $100   $30  $120
5/2/19  $120   $56  $134
5/3/19   $89  $231   $90


0 commentaires