Как удалить не нужные строки прочитанные из файла по частям?
Есть .txt список в таком виде:
vasya:true12
gena:false9999
petya:true888
oleg:falsetrue
fan:falsetrue909
Нужно удалить всю строку, в которой после двоеточия слово не содержит букву, либо не содержит цифру, либо длина меньше 8 символов.
Для приведенных выше данных, результат должен быть такой:
gena:false9999
fan:falsetrue909
Список очень большой, потому важна скорость работы. И метод читать файл построчно не подходит, т.к. это долго.
Решил использовать Pandas, чтобы читать файл частями, а именно:
import pandas as pd
import re
file = 'test.txt'
chunker = pd.read_table(file,chunksize=10000)
for chunk in chunker:
print(chunk)
Но вот как из каждой части удалить не нужные строки, не знаю.
Ответы (2 шт):
Раз уж метка регулярные-выражения, то вот.
Но вообще-то надо просто читать файл и сразу его парсить и обрабатывать.
console.log(`vasya:true12
gena:false9999
petya:true888
oleg:falsetrue
fan:falsetrue909
qqq:01234567890`
.replace(/^.*:(.{0,7}|((?!.*(?!\d)\w)|(?!.*\d)).*)\r?$\n?/gm, ""))
Опитонил: https://ideone.com/dHFc8g
import re
s = """vasya:true12
gena:false9999
petya:true888
oleg:falsetrue
fan:falsetrue909
qqq:01234567890"""
print(re.sub(r"^.*:(.{0,7}|((?!.*(?!\d)\w)|(?!.*\d)).*)\r?$\n?", "", s, flags=re.M))
Вариант 1:
chunksize = 10000
min_len = 8
reader = pd.read_csv(filename, sep=":", header=None,
names=["name", "pwd"], chunksize=chunksize)
for df in reader:
mask = df["pwd"].str.contains("\d") & df["pwd"].str.contains("\w") & df["pwd"].str.len().ge(min_len)
# process matched rows
print(df.loc[mask])
Пример работы:
In [24]: df.loc[mask]
Out[24]:
name pwd
1 gena false9999
4 fan falsetrue909
Вариант 2: (используем регулярки, но не используем медленные look ahead и look behind):
chunksize = 10000
min_len = 8
reader = pd.read_csv(filename, sep=":", header=None,
names=["name", "pwd"], chunksize=chunksize)
for df in reader:
mask = ~df["pwd"].str.contains(r"^(?:.{0,7}|\D+|[^\W\d_]+)$")
# -----^ <----- инвертирование маски - чтобы выбрать строки, НЕ удовлятворяющие RegEx
# process matched rows
print(df.loc[~mask])
Замеры времени для 50.000 строк:
In [47]: df = pd.concat([df] * 10000, ignore_index=True)
In [48]: df.shape
Out[48]: (50000, 2)
In [60]: %timeit ~df["pwd"].str.contains(r"^(?:.{0,7}|\D+|[^\W\d_]+)$")
64.4 ms ± 1.66 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [61]: %timeit df["pwd"].str.contains("\d") & df["pwd"].str.contains("\w") & df["pwd"].str.len().ge(min_len)
99.9 ms ± 5.24 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
PS хотел добавить для сравнения времени выполнения вариант от @Qwertiy, но не смог преобразовать его RegEx в такой, чтобы он правильно работал в Python... :(