Добавление новых столбцов в CSV-файл и значения из разных словарей-понимания - PullRequest
0 голосов
/ 01 мая 2019

Это мой код ниже, и я хотел бы написать новый столбец в моем исходном CSV, столбцы должны содержать значения каждого словаря, созданного во время моего кода, и я хотел бы для последнего словаря, так как он содержит 3 значения,что каждое значение вставляется в один столбец.Код для записи в CSV находится в конце, но, возможно, есть способ записать значения каждый раз, когда я создаю новый словарь.

Мой код для маршрута CSV: я не могу понять, как добавить, не удаляя содержимое исходного файла


# -*- coding: UTF-8 -*-
# -*- coding: UTF-8 -*-
import codecs 
import re
import os
import sys, argparse
import subprocess
import pprint
import csv
from itertools import islice
import pickle
import nltk
from nltk import tokenize
from nltk.tokenize import sent_tokenize, word_tokenize
from nltk.corpus import stopwords
import pandas as pd

try:
    import treetaggerwrapper
    from treetaggerwrapper import TreeTagger, make_tags
    print("import TreeTagger OK")
except:
    print("Import TreeTagger pas Ok")

from itertools import islice
from collections import defaultdict

#export le lexique de sentiments
pickle_in = open("dict_pickle", "rb")
dico_lexique = pickle.load(pickle_in)


# extraction colonne verbatim
d_verbatim = {}

with open(sys.argv[1], 'r', encoding='cp1252') as csv_file:
    csv_file.readline()
    for line in csv_file:
        token = line.split(';')
        try:
            d_verbatim[token[0]] = token[1]
        except:
            print(line)

#print(d_verbatim)

#Using treetagger   
tagger = treetaggerwrapper.TreeTagger(TAGLANG='fr')
d_tag = {}
for key, val in d_verbatim.items(): 
        newvalues = tagger.tag_text(val)
        d_tag[key] = newvalues
#print(d_tag)


#lemmatisation  
d_lemma = defaultdict(list)
for k, v in d_tag.items():
    for p in v:
        parts = p.split('\t')
        try:
            if parts[2] == '':
                d_lemma[k].append(parts[0])
            else:
                d_lemma[k].append(parts[2]) 
        except:
            print(parts)
#print(d_lemma) 


stopWords = set(stopwords.words('french'))          
d_filtered_words = {k: [w for w in l if w not in stopWords and w.isalpha()] for k, l in d_lemma.items()}

print(d_filtered_words)     

d_score = {k: [0, 0, 0] for k in d_filtered_words.keys()}
for k, v in d_filtered_words.items():
    for word in v:
        if word in dico_lexique:
            if word 
            print(word, dico_lexique[word]) 

1 Ответ

0 голосов
/ 01 мая 2019

Ваше редактирование, казалось, ухудшило ситуацию, в результате вы удалили много релевантного контекста.Я думаю, что собрал воедино то, что вы пытаетесь сделать.ядро этого, кажется, подпрограмма, которая выполняет анализ настроений над текстом.

Я бы начал с создания класса, который отслеживает это, например:

class Sentiment:
    __slots__ = ('positive', 'neutral', 'negative')

    def __init__(self, positive=0, neutral=0, negative=0):
        self.positive = positive
        self.neutral = neutral
        self.negative = negative

    def __repr__(self):
        return f'<Sentiment {self.positive} {self.neutral} {self.negative}>'

    def __add__(self, other):
        return Sentiment(
            self.positive + other.positive,
            self.neutral + other.neutral,
            self.negative + other.negative,
        )

, который будетПозволяет вам заменить ваши извилистые биты кода, такие как [a + b for a, b in zip(map(int, dico_lexique[word]), d_score[k])] на score += sentiment в функции ниже, и позволяет нам ссылаться на различные значения по имени

. Затем я бы предложил предварительно обработать ваши засоленные данные, поэтомувам не нужно конвертировать вещи в int s в середине несвязанного кода, например:

with open("dict_pickle", "rb") as fd:
    dico_lexique = {}
    for word, (pos, neu, neg) in pickle.load(fd):
        dico_lexique[word] = Sentiment(int(pos), int(neu), int(neg))

, это помещает их непосредственно в вышеприведенный класс и, похоже, соответствует другим ограничениям в вашем коде,но у меня нет ваших данных, поэтому я не могу проверить.

после того, как вы разберете все ваши понимания и циклы, у нас останется одна приятная процедура для обработки одного фрагмента текста:

def process_text(text):
    """process the specified text
    returns (words, filtered words, total sentiment score)
    """
    words = []
    filtered = []
    score = Sentiment()

    for tag in make_tags(tagger.tag_text(text)):
        word = tag.lemma
        words.append(word)

        if word not in stopWords and lemma.isalpha():
            filtered.append(word)

        sentiment = dico_lexique.get(word)
        if sentiment is not None:
            score += sentiment

    return words, filtered, score

и мы можем поместить это в цикл, который читает строки из входных данных и отправляет их в выходной файл:

filename = sys.argv[1]
tempname = filename + '~'

with open(filename) as fdin, open(tempname, 'w') as fdout:
    inp = csv.reader(fdin, delimiter=';')
    out = csv.writer(fdout, delimiter=';')

    # get the header, and blindly append out column names
    header = next(inp)
    out.writerow(header + [
        'd_lemma', 'd_filtered_words', 'Positive Score', 'Neutral Score', 'Negative Score',
    ])

    for row in inp:
        # assume that second item contains the text we want to process
        words, filtered, score = process_text(row[1])
        extra_values = [
            words, filtered,
            score.positive, score.neutal, score.negative,
        ]
        # add the values and write out
        assert len(row) == len(header), "code needed to pad the columns out"
        out.writerow(row + extra_values)

# only replace if everything succeeds
os.rename(tempname, filename)

мы записываем в другой файл и переименовываем только в случае успеха, этоозначает, что в случае сбоя кода он не оставит частично записанные файлы.Хотя я бы не хотел работать так, как обычно, и заставлял бы мои сценарии читать из stdin и писать в stdout.таким образом, я могу работать как:

$ python script.py < input.csv > output.csv

, когда все в порядке, но также позволяет мне запускать как:

$ head input.csv | python script.py

, если я просто хочу проверить с первыми несколькими строками ввода, или:

$ python script.py < input.csv | less

если я хочу проверить вывод по мере его генерирования

обратите внимание, что ни один из этого кода не был запущен, так что, вероятно, в нем есть ошибки, но я действительно могу видетьчто код пытается сделать, как это.Понимание и «функциональный» стиль кода хороши, но они могут легко стать нечитаемыми, если вы не будете осторожны

...