Analyser un csv ligne à ligne à partir de plusieurs listes de mots

a marqué ce sujet comme résolu.

Bonjour à tous,

J'ai posé plusieurs questions ces temps-ci pour réaliser un petit script utile pour mon travail .

Cependant là je cale je pense qu'il y a un problème de conception ou autre je ne vois pas comment trouver une solution .

En gros mon script dans l'ideal marcherait comme suit : 1. Le script va chercher dans un dossier tous les fichiers .txt 2. Il stocke le nom de chaque fichier pour créer une sorte de "catégorie" (par exemple urbanisme.txt le contiendra que des mots clés sur l'urbanisme) 2bis. Il ouvre ce fichier 3. Il crée une liste avec tous les mots-clés du document appelée [sujet]_liste 4. Il va créer des variables pour chaque sujet (ex: urbanisme_clic, urbanisme_engagement …ect) 5. Il va tester pour chaque liste créée en début de document le fichier csv ligne à ligne pour catégoriser chaque ligne (une ligne peut être multi catégorisée donc aucun soucis pas besoin de les exclure du test du sujet 2 si le sujet 1 est positif sur une ligne) 6. Il va ensuite prendre les valeurs du csv de chaque catégorie calculée précédemment pour faire des stats par catégorie

J'ai donc sorti ceci pour tester les fichiers et créer les variables necessaires:

 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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#coding: utf-8
import csv
import os

#--------------------------------------TEST LISTE + CREATION VARIABLES------------------------------------
#---------------------------------------------------------------------------------------------------------
#---------------------------------------------------------------------------------------------------------
#---------------------------------------------------------------------------------------------------------

#Déclaration variables
liste_fichier=[]
liste_document = os.listdir('.')
liste_sujets=[]
#Listing fichiers/documents dans le dossier courant + création liste fichiers
for elt in liste_document:
    chaine=elt
    if chaine.split(".")[-1] =="txt":
        liste_fichier.append(elt)

#Création liste sujets
for elt in liste_fichier:
    chaine=elt
    liste_sujets.append(chaine.split(".")[-2])

#PASSAGE DES VARIABLES
dictionnaire={}
k=0
kmax=len(liste_sujets)

while k<kmax:
    key=liste_sujets[k]
    dictionnaire[key]=open(liste_fichier[k],"r",encoding="utf-8")
    k+=1
k=0
while k<kmax:
    key=liste_sujets[k]+"_compte"
    dictionnaire[key]=0
    k+=1
k=0
while k<kmax:
    key=liste_sujets[k]+"_impression"
    dictionnaire[key]=0
    k+=1
k=0
while k<kmax:
    key=liste_sujets[k]+"_engagement"
    dictionnaire[key]=0
    k+=1
k=0
while k<kmax:
    key=liste_sujets[k]+"_clic"
    dictionnaire[key]=0
    k+=1
k=0
while k<kmax:
    key=liste_sujets[k]+"_liste"
    dictionnaire[key]=[]
    k+=1
k=0
#création variable a la barbare
locals().update(dictionnaire)

et ceci pour les calculs (pour le moment je n'ai pas réuni le tout ensemble car cela justement ne fonctionnais pas)L'ouverture du fichier "finance" étant pour les test mais le but est que le fonctionnement soit automatique en fonction des fichiers trouvés par le script précédent . Donc je ne veux pas coder "en dur" le nom des fichiers à ouvrir car je ne peux les connaître à l'avance:

 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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
fichier = csv.reader(open("test2.csv","r",encoding="utf-8"))
finance=open("finance.txt","r",encoding="utf-8")

#déclaration variables calcul
finance_list=[]
texte_brut=""
texte=[]
impression=0
engagement=0
clic=0
finance_compte=0
finance_impression=0
finance_engagement=0
finance_clic=0


#Création liste test
for ligne in finance:
    finance_list.append(ligne.rstrip("\n"))

#Lecture fichier stat   
for row in fichier:
    texte_brut=row[2]
    texte=texte_brut.split()
    impression=float(row[4])
    engagement=float(row[5])
    clic=float(row[11])
    #test thematique
    for elt in texte:
        if elt in finance_list:
            finance_compte+=1
            finance_impression+=impression
            finance_engagement+=engagement
            finance_clic+=clic
            break
        else:
            continue

finance_compte=int(finance_compte)
finance_impression=int(finance_impression)
finance_engagement=int(finance_engagement)
finance_clic=int(finance_clic)
print("----------------FINANCE----------------")
print("Nombre de Tweet finance : ",finance_compte)
print("Impressions totales : ",finance_impression)
print("Engagement total : ",finance_engagement)
print("Nombre de clics sur les liens : ",finance_clic)
print("---------------------------------------")
os.system("pause")

Je suis bloqué par plusieurs point par exemple comment créer dynamiquement une variable urbanisme=open("urbanisme.txt","r") ? Cela ma semble non recommandé en python voir impossible

Si vous avez des pistes pour aboutir au résultat voulu je suis preneur :)

Merci beaucoup :)

+0 -0

ba justement je suis passé par un dico avec par exemple clé=urbanisme valeur=open("urbanisme.txt","r") cependant ensuite quand je crée la variable avec

locals().update(dictionnaire)

cela n'ouvre pas le fichier ensuite car urbanisme="open("urbanisme.txt","r")" et non urbanisme=open("urbanisme.txt","r")

Donc je suis un peu bloqué :s

J'ai pas tout compris mais ta dernière ligne (locals().update(dictionnaire)) ne peux pas marcher. La doc le dit clairement :

Note The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter.

Pourquoi tu veux les injecter dans le scope courant plutot que de les laisser dans un dictionnaire ?

J'ai trouvé ça sur Stackoverflow et ça semblais répondre à mon soucis mais j'ai clairement pas tout compris au fonctionnement .

Pour moi le but était que les entrées du dico se transforment en variables. Surtout pour la variable [nom fichier]=open("machin.txt","r") pour ouvrir le fichier au bout moment et le fermer ensuite . Le problème étant que je ne peux pas coder en dur l'ouverture des fichiers car je n'en connais pas le nombre ni le nom avant chaque exécution du script .

On pourrait avoir un exemple minimal avec quelques entrées et la sortie attendue ? Je ne comprend pas très bien ce que tu veux faire, mais ça a l'air faisable plus simplement.

EDIT: Et au passage, les déclarations de variables en début de code sont tout à fait inutiles si tu les redéclare plus tard

+0 -0

En gros j'ai un csv avec une liste de tous les tweets d'un compte Twitter et des metrics pour chaque tweet (clic, engagement, retweet …ect)

Le but est par exemple (dans le deuxième code) de choper un fichier finance.txt pour voir tous les mots dedans . Tous ses mots sont foutus dans une liste

Ensuite je parcours le csv et je test chaque tweet pour savoir s'il comprend un de ces mots. Si c'est le cas j'incrémente les variables finance_clic, finance_engagement, finance_retweet …ect des valeurs de ces metrics pour ce tweet

A la fin j'obtient tous les clics généré par des tweets finance , tout l'engagement …ect et je peux aussi avoir la valeur moyenne par sujet :)

Avec le premier code ce que j'essaye de faire c'est d'avoir une version plus "modulaire" à savoir que les utilisateur définiront leur liste de sujets et les mots qu'ils veulent tester en ayant un fichier .txt par sujet (histoire de pas coder en dur ces listes de mots clés)

+0 -0

Le réflexe de vouloir créer des variables absolument n'a pas de sens, pourquoi ne pas simplement travailler sur le dictionnaire ?

En débroussaillant ton code, voici ce que ça donne (pas testé) :

 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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#coding: utf-8
import csv
import os

#Listing fichiers/documents dans le dossier courant + création liste fichiers
liste_fichiers = [elt for elt in os.listdir('.') if elt.endswith(".txt")]

#Création liste sujets
liste_sujets = [elt.split(".")[-2] for elt in liste_fichiers]


dictionnaire = {}

for fichier, sujet in zip(liste_fichiers, liste_sujets):
    fp = open(fichier, "r", encoding="utf-8")
    dictionnaire[sujet] = [ligne.rstrip("\n") for ligne in fp]

for sujet in liste_sujets:
    for suffix in ['compte', 'impression', 'engagement', 'clic']:
        dictionnaire[sujet, suffix] = 0


##############################################################################

fichier = csv.reader(open("test2.csv","r",encoding="utf-8"))

sujet = input("Entrez un sujet: ")

#Lecture fichier stat   
for row in fichier:
    texte_brut = row[2]
    texte = texte_brut.split()
    impression = float(row[4])
    engagement = float(row[5])
    clic = float(row[11])
    #test thematique
    if any(elt in dictionnaire[sujet] for elt in texte):
        dictionnaire[sujet, 'compte'] += 1
        dictionnaire[sujet, 'impression'] += impression
        dictionnaire[sujet, 'engagement'] += engagement
        dictionnaire[sujet, 'clic'] += clic


print("----------------%s----------------" % sujet.upper())
print("Nombre de Tweets : " % dictionnaire[sujet, 'compte'])
print("Impressions totales : " % dictionnaire[sujet, 'impression'])
print("Engagement total : " % dictionnaire[sujet, 'engagement'])
print("Nombre de clics sur les liens : " % dictionnaire[sujet, 'clic'])
print("---------------------------------------")
os.system("pause")
+1 -0

Euh je comprend pas dans ton code le "sujet = input("Entrez un sujet: ")" ? Le but est justement de calculer les valeurs pour TOUS les sujets qui possèdent un fichier.txt à leur nom .

En gros ton script le fait pour un sujet à la fois c'est ca ? (histoire de bien capter ce que tu as fait)

J'ai donné la possibilité de choisir un sujet, il est tout à fait possible de remplacer cette ligne par une boucle for sujet in liste_sujets: et tous les sujets seront traités de la même façon.

Ce qui donne :

 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
#Lecture fichier stat
for row in fichier:

    #Traitement des sujets
    for sujet in liste_sujets:
        texte_brut = row[2]
        texte = texte_brut.split()
        impression = float(row[4])
        engagement = float(row[5])
        clic = float(row[11])
        #test thematique
        if any(elt in dictionnaire[sujet] for elt in texte):
            dictionnaire[sujet, 'compte'] += 1
            dictionnaire[sujet, 'impression'] += impression
            dictionnaire[sujet, 'engagement'] += engagement
            dictionnaire[sujet, 'clic'] += clic

        print("----------------%s----------------" % sujet.upper())
        print("Nombre de Tweets : " % dictionnaire[sujet, 'compte'])
        print("Impressions totales : " % dictionnaire[sujet, 'impression'])
        print("Engagement total : " % dictionnaire[sujet, 'engagement'])
        print("Nombre de clics sur les liens : " % dictionnaire[sujet, 'clic'])
        print("---------------------------------------")

    os.system("pause")
+1 -0

Merci de l'aide :) J'ai un dernier soucis avec ton code :

1
2
3
4
Traceback (most recent call last):
  File "D:\Python\Twitter qui marche\Calcul-Twitter-ZDS.py", line 45, in <module>
    print("Nombre de Tweets : " % dictionnaire[sujet, 'compte'])
TypeError: not all arguments converted during string formatting

J'ai cherché le type d'erreur et je capte pas trop le soucis . il y a un espace de trop entre les % et les dictionnaires ?

Il manque les formatteurs, tu peux remplacer ces lignes par :

1
2
3
4
        print("Nombre de Tweets : %s" % dictionnaire[sujet, 'compte'])
        print("Impressions totales : %s" % dictionnaire[sujet, 'impression'])
        print("Engagement total : %s" % dictionnaire[sujet, 'engagement'])
        print("Nombre de clics sur les liens : %s" % dictionnaire[sujet, 'clic'])

Merci :) au cas ou un ami m'a donné cette solution si ca peut aider quelqu'un qui repasserait par ce sujet :

1
2
3
4
5
6
    print("----------------%s----------------" % sujet.upper())
    print("Nombre de Tweets : {}" .format(dictionnaire[sujet, 'compte']))
    print("Impressions totales : {}" .format(dictionnaire[sujet, 'impression']))
    print("Engagement total : {}" .format(dictionnaire[sujet, 'engagement']))
    print("Nombre de clics sur les liens : {}" .format(dictionnaire[sujet, 'clic']))
    print("---------------------------------------")

Par contre ton code fait quelque chose de bizarre : il donne des stats qui sont bonnes mais simplement pour le premier sujet en ordre alphabétique ensuite le reste est à 0 (mais c'est bien affiché juste tout est à 0)

Par exemple avec 3 fichiers : finance.txt urbanisme.txt et securite.txt ca donne des stats que pour finance . C'est normal ?

Non, ce n'est pas normal. Mais je viens de me rendre compte que mon affichage est mal placé. Essaye en mode séparé comme ceci :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#Lecture fichier stat
for row in fichier:
    texte_brut = row[2]
    texte = texte_brut.split()
    impression = float(row[4])
    engagement = float(row[5])
    clic = float(row[11])

    #Traitement des sujets
    for sujet in liste_sujets:
        if any(elt in dictionnaire[sujet] for elt in texte):
            dictionnaire[sujet, 'compte'] += 1
            dictionnaire[sujet, 'impression'] += impression
            dictionnaire[sujet, 'engagement'] += engagement
            dictionnaire[sujet, 'clic'] += clic

for sujet in liste_sujets:
    print("----------------%s----------------" % sujet.upper())
    print("Nombre de Tweets : %s" % dictionnaire[sujet, 'compte'])
    print("Impressions totales : %s" % dictionnaire[sujet, 'impression'])
    print("Engagement total : %s" % dictionnaire[sujet, 'engagement'])
    print("Nombre de clics sur les liens : %s" % dictionnaire[sujet, 'clic'])
    print("---------------------------------------")
    os.system("pause")
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte