IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Compare 2 CSV


Sujet :

Python

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 196
    Points : 61
    Points
    61
    Par défaut Compare 2 CSV
    Bonjour à tous
    Voila j'ai besoin de comparer 2 fichier CSV qui n'ont pas tout à fait la meme structure.
    je ne sais pas par ou commencer soit transformer un des 2 fichiers pour effectuer ma comparaison soit partir de la structure présente est faire la comparaison directement .
    les fichiers se présentent sous la forme qui suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    fichier A :
    List  ---- Team    ---- Ownner 1 ---- Ownner 2
    93710 ---- EquipeA ---- DOE, John ---- BOND, James
    93710 ---- EquipeB ---- SMITH, Will ----
    04710 ---- EquipeE ---- EASTWOOD, Clint ---- CRUISE, Tom
    04710 ---- EquipeF ---- WILLIS, Bruce ----
    04710 ---- EquipeG ---- CLOONEY, Georges ----
    04710 ---- EquipeH ---- CAREY, Jim ---- PENN, Sean
    04710 ---- EquipeI ---- FORD, Harrisson ---- BRANDO, Marlon
    *******************************************************************
    Fichier B : 
    File ---- Equipe_Name ---- Owner_Name
    93710 ---- EquipeA ---- DOE, John
    93710 ---- EquipeA ---- BOND, James
    93710 ---- EquipeB ---- SMITH, Will
    04710 ---- EquipeC ---- PITT, Brad
    04710 ---- EquipeC ---- SMITH, Will
    04710 ---- EquipeD ---- HANKS, Tom
    04710 ---- EquipeD ---- DEEP, Johnny
    04710 ---- EquipeC ---- PITT, Brad
    04710 ---- EquipeC ---- SMITH, Will
    04710 ---- EquipeE ---- EASTWOOD, Clint
    04710 ---- EquipeE ---- CRUISE, Tom
    04710 ---- EquipeF ---- WILLIS, Bruce
    04710 ---- EquipeG ---- CLOONEY, Georges
    04710 ---- EquipeH ---- CAREY, Jim
    04710 ---- EquipeH ---- PENN, Sean
    04710 ---- EquipeI ---- FORD, Harrisson
    04710 ---- EquipeI ---- BRANDO, Marlon
    24710 ---- EquipeC ---- PITT, Brad
    24710 ---- EquipeC ---- SMITH, Will
    34710 ---- EquipeC ---- PITT, Brad
    34710 ---- EquipeC ---- SMITH, Will
    Sachant que pour le fichier B la colone Owner Name ne se présentait pas comme présentait mais plutot sous la forme domain.com\name je l'ai splité pour etre plus proche
    le fichier est le fichier A de référence


    Merci de m'aiguiller

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Citation Envoyé par djbad Voir le message
    Merci de m'aiguiller
    Pour comparer, il faut savoir à quelles conditions vous allez pouvoir dire qu'ils sont "égaux" ou pas.
    Et en regardant cela en diagonale, vous avez des équipes et des joueurs dans chacune de ces équipes. Donc, vous pourriez extraire de chacun de ces fichiers un dictionnaire dont la clef serait équipe et la valeur associé la liste des joueurs.... Puis comparer les dictionnaires.
    note: pour autant que ce soit cela que vous vouliez comparer...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 196
    Points : 61
    Points
    61
    Par défaut
    le point de comparaison sera double il doivent avoir
    la même référence qui correspond à un nom de serveur (Ficher A c'est List et de l'autre c'est File)
    et la meme équipe dans le fichier A c'est Team et dans le fichier B c'est Equipe_Name
    pour moi le premier element à comparer le serveur ensuite si c'est le meme serveur est ce qu'ils ont la meme TEAM

    Voici les fichiers tels qu'ils sont:
    FichierA
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Index;List;Team;Access;ALIVE;Propriétaire 1;Propriétaire 1 - mail;Propriétaire 2;Propriétaire 2 - mail;Propriétaire 3;Propriétaire 3 - mail;Commentaire
    3502;93710;EquipeA;VIP;OUI;DOE, John;dj@theworld.com;BOND, James;bj@theworld.com;;;
    11;93710;EquipeB;VIP2;OUI;SMITH, Will;sw@theworld.com;;;;;
    5742;04710;EquipeE;VIP;OUI;EASTWOOD, Clint;ec@theworld.com;CRUISE, Tom;ct@theworld.com;;;
    212;04710;EquipeF;Standard;OUI;WILLIS, Bruce ;wb@theworld.com;;;;;
    2221;04710;EquipeG;Standard;OUI;CLOONEY, Georges;cg@theworld.com;;;;;
    5444;04710;EquipeH;VIP;OUI;CAREY, Jim;cj@theworld.com;PENN, Sean;ps@theworld.com;;;
    446;04710;EquipeI;VIP2;OUI;FORD, Harrisson ;fh@theworld.com;BRANDO, Marlon;bm@theworld.com;;;
    FichierB
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    File;Equipe_Name;Owner_Name;info;Path;Number_of_Files_in_Subfolders;Email;Department
    93710;EquipeA;theworld.com\DOE, John;acteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    93710;EquipeA;theworld.com\BOND, James;figurant;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    93710;EquipeB;theworld.com\SMITH, Will;acteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    04710;EquipeC;theworld.com\PITT, Brad;producteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    04710;EquipeC;theworld.com\SMITH, Will;acteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    04710;EquipeD;theworld.com\HANKS, Tom;producteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    04710;EquipeD;theworld.com\DEEP, Johnny;acteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    04710;EquipeC;theworld.com\PITT, Brad;producteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    04710;EquipeC;theworld.com\SMITH, Will;figurant;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    04710;EquipeE;theworld.com\EASTWOOD, Clint;acteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    04710;EquipeE;theworld.com\CRUISE, Tom;producteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    04710;EquipeF;theworld.com\WILLIS, Bruce;acteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    04710;EquipeG;theworld.com\CLOONEY, Georges;producteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    04710;EquipeH;theworld.com\CAREY, Jim;acteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    04710;EquipeH;theworld.com\PENN, Sean;producteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    04710;EquipeI;theworld.com\FORD, Harrisson;figurant;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    04710;EquipeI;theworld.com\BRANDO, Marlon;acteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    24710;EquipeC;theworld.com\PITT, Brad;producteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    24710;EquipeC;theworld.com\SMITH, Will;acteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    34710;EquipeC;theworld.com\PITT, Brad;producteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    34710;EquipeC;theworld.com\SMITH, Will;acteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    le code que j'ai commencé est le suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    Listf1 = []
    Listf2 = []
    def file3(NameFile):
    	with open(NameFile) as csvfile:
    			reader = csv.DictReader(csvfile, delimiter=';')
    			for row in reader :
    				list_tmp=[row ['List'], row['Team'], row ['Propriétaire 1'], row['Propriétaire 2']]
    				Listf1.append(list_tmp)
    	return (Listf1)
     
    def file4(NameFile):
    	with open(NameFile) as csvfile:
    			reader = csv.DictReader(csvfile, delimiter=';')
    			for row in reader :
    				domain,name=row['Owner_Name'].split("\\")
    				list_tmp2=[row ['File'], row['Equipe_Name'], name]
    				Listf2.append(list_tmp2)
    	return (Listf2)
     
     
    file3('FichierA.csv')
    file4('FichierB.csv')
    #pour afficher juste l'exemple
    print (Listf1[0])
    print (Listf2[0:3])
    j'étais parti pour comparer 2 listes mais je ne vois comment comparer face a cette structure
    Ah oui c'est du python3.6 au cas où

  4. #4
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut
    La structure que j'aurais utilisé et sans doute la plus simple serait des set de tuples, l'utilisation de sets facilitera la tâche pour trouver les éléments communs avec sa méthode intersection (&).
    Le temps ronge l'amour comme l'acide.

  5. #5
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Tout dépend de la taille des 2 fichiers csv. S'ils sont de taille limitée, par exemple <5000 lignes, on peut faire simple.

    Il s'agit alors de faire des comparaisons entre 2 "listes de listes", chaque sous-liste représentant une ligne du fichier csv.

    Par exemple, voilà une fonction simple de lecture d'un fichier csv:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def lirecsv(fichier, entete=False, encoding=None):
        """lit le fichier csv et retourne une liste de listes
           si entete=True, retire la 1ère ligne d'entête
        """
        with open(fichier, 'r', newline='', encoding) as fs:
            lliste = []
            for ligne in csv.reader(fs, delimiter=';'):
                lliste.append(ligne)
        if entete:
            lliste.pop(0)
        return lliste
    Si on applique aux 2 listes A.csv et B.csv:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    llisteA = lirecsv("A.csv", True)
    llisteB = lirecsv("B.csv", True)
    On obtient pour llisteA:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [['3502', '93710', 'EquipeA', 'VIP', 'OUI', 'DOE, John', 'dj@theworld.com', 'BOND, James', 'bj@theworld.com', '', '', ''],
    ['11', '93710', 'EquipeB', 'VIP2', 'OUI', 'SMITH, Will', 'sw@theworld.com', '', '', '', '', ''],
    ['5742', '04710', 'EquipeE', 'VIP', 'OUI', 'EASTWOOD, Clint', 'ec@theworld.com', 'CRUISE, Tom', 'ct@theworld.com', '', '', ''],
    ['212', '04710', 'EquipeF', 'Standard', 'OUI', 'WILLIS, Bruce ', 'wb@theworld.com', '', '', '', '', ''],
    ... ]
    Et pour llisteB:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [['93710', 'EquipeA', 'theworld.com\\DOE, John', 'acteur', 'THEWORLDWILD', '0', '@theworld.com', 'HOLYWOOD'],
    ['93710', 'EquipeA', 'theworld.com\\BOND, James', 'figurant', 'THEWORLDWILD', '0', '@theworld.com', 'HOLYWOOD'],
    ['93710', 'EquipeB', 'theworld.com\\SMITH, Will', 'acteur', 'THEWORLDWILD', '0', '@theworld.com', 'HOLYWOOD'],
    ['04710', 'EquipeC', 'theworld.com\\PITT, Brad', 'producteur', 'THEWORLDWILD', '0', '@theworld.com', 'HOLYWOOD'],
    ... ]
    On peut, bien sûr, compléter ce code pour lui faire traiter des situations plus complexes. Ne pas oublier, en particulier, l'encodage s'il y a des accents. On peut même créer un profil si on fait des échanges avec un tableur (voir la doc).

    Pour chercher un élément dans ces listes de listes, j'utilise une fonction de recherche toute simple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def cherchedanslliste(elem, lliste, indcol):
        """Retourne la liste des indices i dans la liste de listes "lliste" 
           quand lliste[i][indcol]==elem. Si non trouvé, retourne la liste vide
        """
        return [i for i, liste in enumerate(lliste) if elem==liste[indcol]]
    Par exemple, si je recherche "EquipeA" (dans llisteA à l'indice 2), dans llisteB à l'indice 1:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    print(cherchedanslliste("EquipeA", llisteB, 1))
    [0, 1]
    Ayant ces indices trouvés dans llisteB, on a facilement les lignes concernées => llisteB[0] et llisteB[1], dont on peut extraire les autres informations.

    Bien sûr, si les fichiers csv étaient très grands, et pire encore, s'ils ne pouvaient tenir en mémoire, il faudrait utiliser d'autres solutions, mais dans ce cas, être plus précis sur les traitements à faire.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par djbad Voir le message
    le point de comparaison sera double il doivent avoir
    la même référence qui correspond à un nom de serveur (Ficher A c'est List et de l'autre c'est File)
    et la meme équipe dans le fichier A c'est Team et dans le fichier B c'est Equipe_Name
    pour moi le premier element à comparer le serveur ensuite si c'est le meme serveur est ce qu'ils ont la meme TEAM
    C'est toujours une clef (93710) avec des informations associées [ A, B, C] représentées dans les deux fichiers sous une forme différente.
    Donc il faut partir de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3502;93710;EquipeA;VIP;OUI;DOE, John;dj@theworld.com;BOND, James;bj@theworld.com;;;
    11;93710;EquipeB;VIP2;OUI;SMITH, Will;sw@theworld.com;;;;;
    ou de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    93710;EquipeA;theworld.com\DOE, John;acteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    93710;EquipeA;theworld.com\BOND, James;figurant;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    93710;EquipeB;theworld.com\SMITH, Will;acteur;THEWORLDWILD;0;@theworld.com;HOLYWOOD
    pour arriver à 93710 (la clef) => [ "BOND, James", "DOE, John", "SMITH, Will" ] (une liste triée).

    Après vous savez comparer ces choses là:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    >>> d = { 1: ['aa', 'bb', 'cc' ], 2: ['dd', 'ee', 'ff' ]}
    >>> e = { 1: ['aa', 'bb', 'cc' ], 2: ['dd', 'xx']}
    >>> d[1] == e[1]
    True
    >>> d[2] == e[2]
    False
    >>>
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 196
    Points : 61
    Points
    61
    Par défaut
    Merci à tous pour vos conseils
    l'approche dictionnaire m'a l'air d'une bonne approche.
    Mais par exemple sur un meme serveur tu peux avoir plusieurs équipe alors je ne suis pas sur que seul la clé srv est suffisante.
    Peut etre que je me suis mal exprimé. car j'ai besoin d'avoir les mêmes infos des 2 cotés de la liste si je compare et ensuite me dire quels sont les éléments manquants.
    Il se peut que par exemple sur un meme serveur j'ai une autre team avec les mêmes membres que l'équipe A

    une approche du genre {'srv': '93710', 'Team': 'EquipeA', 'Member': ['DOE, John', 'BOND, James']} ne serait pas plus adapté ?
    ou Utiliser des tuples comme clé K1(93710;EquipeA)= ['DOE, John', 'BOND, James']
    il faut que je prenne du recul j'ai l'impression de m'emeler les pinceaux

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par djbad Voir le message
    une approche du genre {'srv': '93710', 'Team': 'EquipeA', 'Member': ['DOE, John', 'BOND, James']} ne serait pas plus adapté ?
    ou Utiliser des tuples comme clé K1(93710;EquipeA)= ['DOE, John', 'BOND, James']
    il faut que je prenne du recul j'ai l'impression de m'emeler les pinceaux
    Vous avez deux problèmes à traiter.
    Le premier est de récupérer les données de chaque fichier pour en faire une information cohérente.
    par exemple passer de la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    3502;93710;EquipeA;VIP;OUI;DOE, John;dj@theworld.com;BOND, James;bj@theworld.com;;;
    au tuple: (93710, "EquipeA", [ "DOE, John", "BOND, James" ])Le deuxième est d'organiser ces informations dans une structure de données qui permettra de faire la comparaison de ces informations. Un dictionnaire où les clefs serait un tuple comme d[(93710, "EquipeA")] ou un dictionnaire contenant autre dictionnaire de listes d[93710]["EquipeA"], c'est une représentation différentes des mêmes informations avec des implications limitées sur le code qui fera le boulot de comparaison.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. Script pour comparer fichiers csv et créer fichier de sortie
    Par rlelamer dans le forum AppleScript
    Réponses: 6
    Dernier message: 13/06/2017, 22h21
  2. Comparer deux fichiers csv
    Par kerplouz dans le forum Général Python
    Réponses: 1
    Dernier message: 21/11/2012, 21h17
  3. Comparer les lignes d'un fichier .csv
    Par mario3979 dans le forum Shell et commandes GNU
    Réponses: 6
    Dernier message: 05/06/2012, 14h08
  4. comparer table et csv
    Par laure07 dans le forum Langage
    Réponses: 10
    Dernier message: 10/05/2012, 16h32
  5. Comparer le contenu d'une table avec un fichier csv
    Par cdo22 dans le forum Requêtes
    Réponses: 3
    Dernier message: 21/11/2008, 18h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo