Уведомления

Группа в Telegram: @pythonsu

#1 Июль 28, 2014 08:38:51

BE_LIKE_A_MAN
Зарегистрирован: 2014-07-25
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Парсинг больших файлов

Здравствуйте!
Программа должна перемешивать определённые слова в заданном соотношении. Определенные слова в данном случае Components=“Pb” и Components=“Cd”. Соотношение задается с помощью процентов.
Проблема в том, что в промежуточном файле вывода не все искомые строки. Отсюда, когда искомые слова вставляются на исходные места, файл вывода оказывается в несколько раз короче входного.

import random, re
with open("infile.txt",'r') as f:
    lines = f.read()
component_1 = re.findall('([^\s].*?Components="Cd".*?)', lines) # что ищем
component_2 = re.findall('([^\s].*?Components="Pb".*?)', lines)
def count(com1, com2):
    result = []
    if com1 != 0:
        l_1 = len(com1)
        a = input('Cd ')
    else:
        l_1 = 0
    if com2 != 0:
        l_2 = len(com2)
        b = input('Pb ')
    else:
        l_2 = 0
    if round(l_1//100) < 1:
        nominal_1_proc = round(l_1//100)+1
    else:
        nominal_1_proc = round(l_1//100)
    if round(l_2//100) < 1:
        nominal_2_proc = round(l_2//100)+1
    else:
        nominal_2_proc = round(l_2//100)
    if com1 != 0:
        for x in range(0, int(a*nominal_1_proc)):
            result.append(com1[x])
    if com2 != 0:
        for y in range(0, int(b*nominal_2_proc)):
            result.append(com2[y])
    random.shuffle(result)
    return result
fo = open("demooutfile.txt", "w")
for y in count(component_1, component_2):
    fo.write(y)
    fo.write('\n')
fo.close()
regex3= re.compile('Components="Pb"|Components="Cd"') # что ищем
with open("infile.txt",'r') as f3:
    lines3 = f3.read()
endpos3=0
match3= regex3.search(lines3,endpos3)
matches3=[] # массив с совпадениями
strings3=[] # все остальное что не совпало, при этом если два совпадения подряд, или начало (конец) строки и совпадение, то в этот массив попадает пустая строка
    # поэтому значения в массивах чередуются относительно целевой строки
while (match3):
 strings3+= [ lines3[endpos3:match3.start()] ]
 endpos3= match3.end()
 matches3+=[match3.group(0)]
 match3= regex3.search(lines3,endpos3)
if (endpos3==len(lines3)): strings3+= [ "" ]
random.shuffle(matches3)
regex2= re.compile('Components="Pb"|Components="Cd"') # что ищем
with open("demooutfile.txt",'r') as f2:
    lines2 = f2.read()
endpos2=0
match2= regex2.search(lines2,endpos2)
matches2=[] # массив с совпадениями
strings2=[] # все остальное что не совпало, при этом если два совпадения подряд, или начало (конец) строки и совпадение, то в этот массив попадает пустая строка
    # поэтому значения в массивах чередуются относительно целевой строки
while (match2):
 strings2+= [ lines2[endpos2:match2.start()] ]
 endpos2= match2.end()
 matches2+=[match2.group(0)]
 match2= regex2.search(lines2,endpos2)
if (endpos2==len(lines2)): strings2+= [ "" ]
random.shuffle(matches2)
result3= "" # собираем строку обратно с перемешанными данными
for i in range(len(matches2)):
 result3+=strings3[i]+matches2[i]   # вместо исходного массива вставляем искомый
result3+=strings3[-1]
with open("outfilenew.txt", "w") as f4:
    f4.write(result3)

Прикреплённый файлы:
attachment infile.txt (252,3 KБ)

Офлайн

#2 Авг. 16, 2014 22:52:25

Master_Sergius
Зарегистрирован: 2013-09-12
Сообщения: 271
Репутация: +  7  -
Профиль   Отправить e-mail  

Парсинг больших файлов

Во-первых, отформатируйте код нормально. Чтобы здесь отображались пустые строки, там просто пропишите пробел.
Во-вторых, слишком много if/else аж глазам больно. В-третьих, можно пример входных и выходных данных? (на примере маленького файлика, до 10 строк)



———————————————————————————
Мой блог о семействе *nix: http://nixtravelling.blogspot.com/

Офлайн

#3 Авг. 17, 2014 08:51:07

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  252  -
Профиль   Отправить e-mail  

Парсинг больших файлов

Я из вашего описания вообще не понял зачем вам входной файл. Надо премешивать Pb Cd ну и перемешивайте. Поэтому мне непонятно ваше недовольство длинной выходного файла.



Офлайн

#4 Авг. 20, 2014 15:02:33

BE_LIKE_A_MAN
Зарегистрирован: 2014-07-25
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Парсинг больших файлов

Уважаемый Master_Sergius, входной файл присутствует, он прикреплён к сообщению. Файл вывода - это входной файл, с перемешанными Components=“Pb” и Components=“Cd” (кроме них множество других) в заданном соотношении.

Офлайн

#5 Авг. 20, 2014 15:05:52

BE_LIKE_A_MAN
Зарегистрирован: 2014-07-25
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Парсинг больших файлов

Уважаемый doza_and, выходной файл - файл с такой же структурой, как и входной. Если он короче, то программа моделирования его не обработает(.

Офлайн

#6 Авг. 20, 2014 15:09:23

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  252  -
Профиль   Отправить e-mail  

Парсинг больших файлов

Уважаемый BE_LIKE_A_MAN попробую сообразить как вам проще сделать.
Такое подойдет?

import re
import numpy as np
def f(found):
    i=np.random.uniform()
    if i<0.3:
        return 'Components="Pb"'
    else:
        return 'Components="Cd"'
data=open("infile.txt","r").read()
data1=re.sub('Components="\d\d"',f,data)
open("outfile.txt","w").write(data1)

ps
этот файл не большой он маленький. если будет большой то sub его не возьмет.



Отредактировано doza_and (Авг. 20, 2014 15:25:32)

Офлайн

#7 Авг. 20, 2014 15:38:31

BE_LIKE_A_MAN
Зарегистрирован: 2014-07-25
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Парсинг больших файлов

doza_and, файл вывода получился идентичным входному(PyScripter-Portable 2.7.5.1). У Вас так же? После i< указывается доля компонента?

Отредактировано BE_LIKE_A_MAN (Авг. 20, 2014 15:55:20)

Офлайн

#8 Авг. 20, 2014 16:22:14

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  252  -
Профиль   Отправить e-mail  

Парсинг больших файлов

BE_LIKE_A_MAN
После i< указывается
Да доля компонента. Поправьте регулярку как вам нужно. Сейчас настроено на Components=“22” и тому подобное. Ваш файл не пробовал конвертировать.



Офлайн

#9 Авг. 20, 2014 20:26:48

BE_LIKE_A_MAN
Зарегистрирован: 2014-07-25
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Парсинг больших файлов

doza_and, вот что получилочь:
Для доли Pb от 0 до 0,5:

import re
import numpy as np
def f(found):
    i=np.random.uniform()
    if i<0.3:
        return 'Components="Pb"'
    else:
        return 'Components="Cd"'
data=open("infile.txt","r").read()
data1=re.sub('Components="Pb"',f,data)
open("outfile.txt","w").write(data1)
Для доли Cd от 0 до 0,5:
import re
import numpy as np
def f(found):
    i=np.random.uniform()
    if i<0.3:
        return 'Components="Cd"'
    else:
        return 'Components="Pb"'
data=open("infile.txt","r").read()
data1=re.sub('Components="Cd"',f,data)
open("outfile.txt","w").write(data1)
Постараюсь объединить и сделать оформление в Tkinter, но это уже второстепенное. Главное - работает!
Большое спасибо! +rep

Офлайн

#10 Авг. 20, 2014 21:46:11

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  252  -
Профиль   Отправить e-mail  

Парсинг больших файлов

Успехов! Добытые самостоятельно знания в 10 раз ценнее подсказок.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version