#python #pandas
#python #pandas
Вопрос:
У меня есть набор данных, который содержит данные, которые выглядят следующим образом:
Month, Year, Quantity Sold, Product Name
11, 2017, 13, "Creatine Powder Supplement - 500g"
11, 2017, 10, "Gummies 1 bag"
11, 2017, 12, "Creatine Powder Supplement - 1000g"
11, 2017, 15, "Creatine Powder Supplement - 1500g"
11, 2017, 11, "Glucosamine - 500g"
11, 2017, 23, "Glucosamine - 1500g"
12, 2017, 17, "Creatine Powder Supplement - 1000g"
12, 2017, 24, "Glucosamine - 500g"
12, 2017, 13, "Glucosamine - 1500g"
1, 2018, 16, "Creatine Powder Supplement - 500g"
1, 2018, 13, "Creatine Powder Supplement - 1000g"
1, 2018, 10, "Gummies 1 bag"
1, 2018, 11, "Glucosamine - 500g"
1, 2018, 21, "Glucosamine - 1500g"
Я хочу рассчитать общий вес проданных товаров, разделенных месяцем и годом, для чего потребуется извлечь вес продукта из столбца «Название продукта», умножив его на столбец «Проданное количество», а затем предоставить общую сумму для соответствующего продукта.
Желаемый результат (я рассчитал только общий вес, проданный для первой строки):
Matched data set:
Month, Year, Product Name, Total Weight Sold
11, 2017, Creatine Powder Supplement, 41000
11, 2017, Glucosamine, <total>
12, 2017, Creatine Powder Supplement, <total>
12, 2017, Glucosamine, <total>
1, 2018, Creatine Powder Supplement, <total>
1, 2018, Glucosamine, <total>
В дополнение к этому, для любых продуктов, которые не заканчиваются шаблоном - <number>g
, я хочу вывести их в отдельный набор данных, чтобы их можно было просмотреть.
UNmatched data set:
Month, Year, Quantity Sold, Product Name
11, 2017, 10, "Gummies 1 bag"
1, 2018, 10, "Gummies 1 bag"
Я подумываю об использовании str.extract
, но я не совсем уверен, как выполнить математику, а затем суммировать полученную вычисленную сумму с другими строками для того же продукта, в новый фрейм данных или иным образом.
Спасибо
Ответ №1:
Самое простое решение, о котором я могу думать, это
product_data = df['Product Name'].str.extract('(?P<name>w ) - (?P<weight>d )g')
invalid_rows = df[product_data['weight'].isnull()]
product_data.drop(labels=invalid_rows.index, inplace=True)
df.drop(labels=invalid_rows.index, inplace=True)
df['Product Name'] = product_data['name']
df['Total'] = product_data['weight'].astype(np.int32) * df['Quantity Sold']
print(df.groupby(['Month', 'Year', 'Product Name']).sum()['Total'].reset_index())
print()
print(invalid_rows)
Какие результаты
Month Year Product Name Total
0 1 2018 Creatine 21000
1 1 2018 Glucosamine 37000
2 11 2017 Creatine 41000
3 11 2017 Glucosamine 40000
4 12 2017 Creatine 17000
5 12 2017 Glucosamine 31500
Month Year Quantity Sold Product Name
1 11 2017 10 "Gummies 1 bag"
11 1 2018 10 "Gummies 1 bag"
Комментарии:
1. Я думаю, что здесь отсутствует вторая часть, чтобы выводить все, что не совпадает отдельно, но это отвечает на первое. Я собираюсь обновить пример набора данных в вопросе, чтобы включить несоответствующие данные.
2. Так близко! Я не упомянул, что название продукта часто состоит из нескольких слов. Я отредактировал, чтобы отразить. Предоставленное регулярное выражение этого не фиксирует.
Ответ №2:
Вот решение на Python. Он записывает строки с ошибками в выходной файл и записывает исправные строки в терминал.
from collections import defaultdict
import re
d = defaultdict(int)
with open('f0.txt', 'r') as f, open('err.txt', 'w') as fout:
fout.write(f.readline()) # print header to err.txt
for row in f:
row = row.rstrip()
if re.search(r'- d g"', row):
month, yr, qty, product = row.split(', ')
product = product.replace('g', '').replace('"', '')
name, grams = product.split(' - ')
key = ','.join([month, yr, name])
d[key] = int(qty) * int(grams)
else:
# handle this row (that doesn't have a Product and weight)
fout.write(row 'n')
print(','.join(['Month', 'Year', 'Product Name', 'Total Sold']))
for key, total in d.items():
print(f'{key},{total}')
Выводит на терминал:
Month,Year,Product Name,Total Sold
11,2017,Creatine,41000
11,2017,Glucosamine,40000
12,2017,Creatine,17000
12,2017,Glucosamine,31500
1,2018,Creatine,21000
1,2018,Glucosamine,37000
Выводит в err.txt:
Month, Year, Quantity Sold, Product Name
11, 2017, 10, "Gummies 1 bag"
1, 2018, 10, "Gummies 1 bag"