У меня есть список лицензий и связанных с ними счетчиков лицензий, например:
1 Third Party SIP Device Seat
1 Third Party SIP Device Seat
1 Third Party SIP Device Seat
3 Station
3 Station
3 Station
20 Station
Списки никогда не находятся в одном и том же порядке, и мне просто нужно добавить итоги для каждого типа лицензии, поэтому в примере я хотел бы получить результат:
3 Third Party SIP Device Seat
29 Station
Данные вводятся в несохраненный блокнот, а затем перемещаются в базу данных. Использование Excel неприменимо, так как это пробелы между числами и именами, а не вкладки.
Каким будет самый простой способ выполнить эту задачу?
«Каким будет самый простой способ выполнить эту задачу?» Использование python для автоматизации всего этого звучит как простой способ выполнить задачу.
Вы можете использовать пакет python pandas. Как заявил @Will, большинство инструментов, включая pandas и excel, могут использовать любой разделитель для чтения текстового файла.
Если бы я разделил пробелами, это испортило бы имена, и у меня осталась бы куча ненужных вкладок в именах, которые мне потом пришлось бы удалить.
@TrebledJ Это цель, я просто не знаю, как это сделать. Какую библиотеку я бы использовал?
Прочитайте строки файла, разбейте каждую по индексу первого пробела, проанализируйте число как целое и создайте словарь лицензии для общего количества. Идти!
itertools имеет группу. не нужны панды
Вот супер уродливое решение:
from functools import reduce
from collections import defaultdict
lines = [ # replace with e.g: with open('input.txt', 'r') as f: lines = f.readlines()
"1 Third Party SIP Device Seat",
"1 Third Party SIP Device Seat",
"1 Third Party SIP Device Seat",
"3 Station",
"3 Station",
"3 Station",
"20 Station"
]
def f(acc, x):
acc[" ".join(x.split(" ")[1:])] += int(x.split(" ")[0]) # first element is the count, everything after we use as "key"
return acc
r = dict(reduce(f, lines, defaultdict(int)))
print(r)
# {'Third Party SIP Device Seat': 3, 'Station': 29}
# to write to file:
with open("output.txt", "w") as f:
for k, v in r.items():
f.write(str(v) + " " + str(k))
Мне нравится использовать defaultdict и уменьшить. умная
@Jeppe Так что это идеально, именно то, что я искал. Я добавил еще несколько шагов к обработке данных, чтобы заставить ее работать, в основном добавляя первую вкладку для каждой строки, а также кавычки и запятую в конце, и все работает как часы. С учетом сказанного можно ли извлечь данные в новый файл Word? Таким образом, я мог бы автоматически сохранять данные для каждой компании в их собственном текстовом документе с именем файла, которое я каждый раз задавал в коде? Кроме того, вместо разделения записей можно использовать новую строку? Я очень ценю помощь.
Мне действительно просто нужно иметь возможность сохранить в документ Word, оттуда я могу просто найти и заменить каждый на новую строку.
@KevinBurris Я добавил код для записи содержимого в файл. Вы можете изменить разделитель и т. д. в строке, построенной в строке f.write(str(v) + " " + str(k))
. Это то, что вы имеете в виду?
Большое вам спасибо за вашу помощь! Я изменил последнюю строку следующим образом: f.write(str(v) + " " + str(k) + "\n"), и теперь я получаю все, что мне нужно! Теперь, когда мой проект работает, я могу полностью автоматизировать процесс и потратить некоторое время на изучение того, как работает этот код и код из других ответов. Я очень ценю, что вы нашли время, чтобы помочь мне, когда я углубляюсь в Python!
@KevinBurris Нет проблем, не стесняйтесь спрашивать об обратном. Функцию f(acc, x)
, вероятно, можно немного почистить.
Вы хотите группу. К счастью, у itertools есть один
from itertools import groupby
text = """1 Third Party SIP Device Seat
1 Third Party SIP Device Seat
1 Third Party SIP Device Seat
3 Station
3 Station
3 Station
0 Station"""
# clean stuff up and split on first space
lines = [line.strip().split(" ", 1) for line in text.split("\n")]
# groupby
result = []
for k, g in groupby(lines, lambda x: x[1]):
total = 0
for i in g:
total += int(i[0])
result.append([k, total])
print(result)
Полное решение с данными в «сохраненном файле блокнота» с именем licences.txt
:
from collections import Counter
counter=Counter()
with open ('licences.txt','r') as f:
for line in f:
count,*words = line.split()
counter[" ".join(words)] += int(count)
with open('grouped_licences.txt','w') as f:
for licence,total in counter.items():
f.write(str(total) + " " + licence + "\n")
Тогда результат в файле grouped_licences.txt
:
3 Third Party SIP Device Seat
29 Station
Другое решение с pandas
:
df=pandas.read_csv('licences.txt', sep = " ",header=None).fillna("")
df["licence"]=df.iloc[:,1:].apply(" ".join,axis=1)
print(df.groupby("licence")[0].sum())
Для :
licence
Station 29
Third Party SIP Device Seat 3
Ну, вы можете указать Excel разделить ваши данные по пробелу или любому другому разделителю по вашему выбору.