1. Введение

В этом проекте мы будем изучать Набор данных распределительного центра Mega Star, комплексный набор данных для моделирования, ориентированный на складирование и логистику. Этот набор данных, занимающий площадь более 50 000 квадратных метров и более 60 000 различных местоположений для продуктов, предоставляет ценную возможность углубиться в управление запасами в больших масштабах.

Набор данных состоит из четырех основных компонентов:

  1. Список продуктов: содержит важную информацию обо всех продуктах, хранящихся в центре распределения, например названия, описания, уникальные идентификаторы и другие атрибуты, относящиеся к управлению запасами.
  2. Складские запасы: предлагает подробный отчет об инвентаризации, демонстрирующий текущий уровень запасов продуктов и их соответствующее расположение на объекте. Анализ этих данных помогает оптимизировать пространство для хранения и эффективно пополнять запасы.
  3. Записи о получении: отслеживает действия по получению в течение пяти дней, включая входящие поставки, количество продукции, происхождение и ответственный персонал. Эти данные дают представление об эффективности процесса приема.
  4. Записи комплектации: Документирует процесс выполнения заказов клиентов в течение одного и того же пятидневного периода. Он включает подробную информацию о выбранных продуктах, количествах, местах получения и задействованном персонале, что помогает оптимизировать выполнение заказов и повысить удовлетворенность клиентов.

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

2. Управление запасами

Как аналитик запасов, контролирующий распределительный центр Mega Star, ваши ежедневные задачи являются неотъемлемой частью бесперебойной работы объекта. Среди этих обязанностей приоритет имеют пять важнейших задач, каждая из которых преследует определенную цель:

  1. Список стоек: эта задача включает в себя создание полной инвентаризации стоек в распределительном центре. Точное количество доступных стоек жизненно важно для эффективного управления пространством для хранения и упрощенной организации продукции.
  2. Список консолидации. Список консолидации — это ключевой инструмент для оптимизации эффективности хранения. Определив возможности для комбинирования или перестановки элементов, вы можете повысить доступность и сократить неиспользуемое пространство.
  3. Контрольный список по определенному списку продуктов. Чтобы вести точный учет запасов, вы будете создавать контрольный список на основе определенного списка продуктов. Это помогает гарантировать, что фактические запасы соответствуют задокументированным количествам, уменьшая несоответствия и потенциальные дефициты.
  4. Список пустых местоположений: отслеживание пустых местоположений необходимо для эффективного управления запасами. Этот список позволяет быстро определить доступное место для хранения поступающих продуктов, сводя к минимуму задержки и максимизируя использование хранилища.
  5. Визуализация: обеспечивает визуальное представление пространственного распределения запасов на объекте. Выявляя «горячие» и «холодные» точки, он играет решающую роль в оптимизации пространства для хранения и улучшении доступности запасов. Полученные данные способствуют повышению операционной эффективности и оптимизации управления запасами.

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

2.1. Список стоек

На этом первом этапе мы создадим «Список количества стоек» для центра распределения Mega Star. Анализируя набор данных «warehouse_stocks.csv» с помощью Pandas, мы получим представление об инвентаризации стеллажей объекта. Кроме того, мы будем использовать набор данных «dc_locations.csv», который содержит информацию обо всех местоположениях на складе.

import pandas as pd
import csv

df = pd.read_csv('warehouse_stocks.csv', low_memory=False)
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 57623 entries, 0 to 57622
Data columns (total 10 columns):
 #   Column       Non-Null Count  Dtype 
---  ------       --------------  ----- 
 0   Product      57623 non-null  object
 1   Description  57623 non-null  object
 2   Category     57623 non-null  object
 3   Brand        57623 non-null  object
 4   Size         57623 non-null  object
 5   Function     57623 non-null  object
 6   Colour       57623 non-null  object
 7   Pallet       57623 non-null  object
 8   Quantity     57623 non-null  int64 
 9   Location     57623 non-null  object
dtypes: int64(1), object(9)
memory usage: 4.4+ MB

df_locations = pd.read_csv('dc_locations.csv', low_memory=False)
df_locations.info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 65856 entries, 0 to 65855
Data columns (total 1 columns):
 #   Column    Non-Null Count  Dtype 
---  ------    --------------  ----- 
 0   Location  65856 non-null  object
dtypes: object(1)
memory usage: 514.6+ KB

Чтобы создать «Список количества стоек» для распределительного центра Mega Star, мы будем использовать предоставленный код Python. Этот код использует библиотеку Pandas для обработки набора данных «warehouse_stocks.csv» и набора данных «dc_locations.csv».

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

Затем функция sort_locations() обрабатывает сгенерированный список местоположений и структурирует их. Он группирует местоположения по префиксу и уровню, вычисляет количество стоек для каждой комбинации префикса и уровня, а затем соответствующим образом сортирует данные.

Наконец, отсортированный и организованный «Список счетчиков стоек» сохраняется в новый CSV-файл с именем «sorted_result.csv».

import pandas as pd

def find_locations(csv_file, prefixes):
    with open(csv_file, 'r') as file:
        reader = csv.reader(file)
        locations = []
        for row in reader:
            if any(row[9].startswith(prefix) for prefix in prefixes):
                locations.append(row)

    locations.sort(key=lambda x: (x[1][:4], x[1][4] if len(x[1]) > 4 else '', x[1][5:] if len(x[1]) > 5 else ''))

    return locations

def sort_locations(result_csv_file):
    df = pd.read_csv(result_csv_file)
    prefixes = df['Location'].str[:2].unique()
    df['Prefix'] = df['Location'].str[:2]
    df['Level'] = df['Location'].str[2:].str.extract(r'(\D+)')
    df.sort_values(['Prefix', 'Level'], inplace=True)
    prefix_level_counts = df.groupby(['Prefix', 'Level']).size()
    df['Prefix Level Count'] = df.apply(lambda row: prefix_level_counts.get((row['Prefix'], row['Level']), 0), axis=1)

    return df


result_csv_file_path = 'warehouse_stocks.csv'

dc_locations_file_path = 'dc_locations.csv'
dc_locations_df = pd.read_csv(dc_locations_file_path)

dc_locations_df['Prefixes'] = dc_locations_df['Location'].str[:2]

prefixes = dc_locations_df['Prefixes'].unique().tolist()

locations = find_locations(result_csv_file_path, prefixes)

new_csv_file_path = 'sorted_locations.csv'
df.to_csv(new_csv_file_path, index=False)

print(f"Sorted locations saved to {new_csv_file_path}.")

sorted_locations = sort_locations(new_csv_file_path)

sorted_result_file_path = 'sorted_result.csv'
sorted_locations.to_csv(sorted_result_file_path, index=False)

print(f"Sorted result saved to {sorted_result_file_path}.")

Sorted locations saved to sorted_locations.csv.
Sorted result saved to sorted_result.csv.

sorted_result_df = pd.read_csv(sorted_result_file_path)
sorted_result_df

2.2. Сводный список

В динамичной среде распределительного центра Mega Star повседневная деятельность часто приводит к созданию множества незакрепленных поддонов. Чтобы обеспечить эффективное использование пространства и рационализировать операции, мы должны регулярно консолидировать эти незакрепленные поддоны. Консолидация включает в себя объединение и перестановку поддонов, оптимизацию складских площадей и минимизацию неиспользуемых площадей на складе.

На следующем этапе нашего проекта анализа запасов мы сосредоточимся на создании «Сводного списка». Этот критический список служит руководством для определения возможностей консолидации поддонов и повышения эффективности хранения.

Мы определим отдельные поддоны, которые могут быть объединены на основе схожих типов продуктов, размеров или местоположения. С помощью этого процесса консолидации мы стремимся уменьшить беспорядок и улучшить доступ к продуктам, что в конечном итоге повысит эффективность работы распределительного центра.

import pandas as pd
import numpy as np
import csv

def extract_count(packsize):
    parts = packsize.split('*')
    count = np.prod([int(part) for part in parts])
    return count

df = pd.read_csv('warehouse_stocks.csv', low_memory=False)

new_df = df.copy()

new_df['Quantity'] = new_df['Quantity'].astype(int)

new_df['Pallet'] = new_df['Pallet'].fillna('0*0*0')

new_df['Count'] = new_df['Pallet'].apply(extract_count)
new_df['Pallet Type'] = np.where(new_df['Quantity'] >= new_df['Count'], 'Full', 'Loose')

new_df.loc[new_df['Count'] == 0, 'Pallet Type'] = np.nan

new_df.to_csv('warehouse_stocks_filtered.csv', index=False)

df1 = new_df[new_df['Quantity'] <= 0.2 * new_df['Count']]

df2 = new_df[(new_df['Quantity'] > 0.2 * new_df['Count']) & (new_df['Quantity'] < 0.6 * new_df['Count'])]

df3 = df1[['Product', 'Description', 'Category', 'Brand', 'Size', 'Function', 'Pallet', 'Quantity', 'Location']].copy()

df3['New location'] = df3['Product'].map(df2.drop_duplicates('Product').set_index('Product')['Location'])

df3 = df3.dropna(subset=['New location'])

output_file = 'consolidation_list.csv'
df3.to_csv(output_file, index=False)

print("Consolidation list is saved to:", output_file)

new_df

Список консолидации содержит информацию об элементах с небольшим количеством и соответствующих им новых местоположениях:

2.3. Контрольный список по продукту

Управление складом с большими запасами может быть сложной задачей, и важно регулярно отслеживать определенные продукты. Чтобы упростить этот процесс, я разработал скрипт Python, который генерирует контрольный список для каждого продукта. Используя два CSV-файла — «warehouse_stocks.csv», содержащий полный перечень товаров, и «list_to_check.csv» с продуктами для проверки — скрипт создает отсортированный контрольный список с такими важными сведениями, как названия продуктов, описания, информация о поддонах, количествах и местонахождении. . Этот автоматизированный подход оптимизирует складские операции, снижает количество ошибок и обеспечивает эффективную проверку запасов, что позволяет лучше контролировать запасы и эффективно удовлетворять потребности клиентов. Окончательный контрольный список легко экспортируется в CSV-файл «checking_sheet.csv» для практического использования и распространения.

import pandas as pd

df = pd.read_csv('warehouse_stocks.csv', low_memory=False)
df.info()

df2 = pd.read_csv('list_to_check.csv')
df2.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 57623 entries, 0 to 57622
Data columns (total 10 columns):
 #   Column       Non-Null Count  Dtype 
---  ------       --------------  ----- 
 0   Product      57623 non-null  object
 1   Description  57623 non-null  object
 2   Category     57623 non-null  object
 3   Brand        57623 non-null  object
 4   Size         57623 non-null  object
 5   Function     57623 non-null  object
 6   Colour       57623 non-null  object
 7   Pallet       57623 non-null  object
 8   Quantity     57623 non-null  int64 
 9   Location     57623 non-null  object
dtypes: int64(1), object(9)
memory usage: 4.4+ MB
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 200 entries, 0 to 199
Data columns (total 1 columns):
 #   Column   Non-Null Count  Dtype 
---  ------   --------------  ----- 
 0   Product  200 non-null    object
dtypes: object(1)
memory usage: 1.7+ KB
product_list = df2['Product'].tolist()

filtered_df = df[df['Product'].isin(product_list)]

filtered_df = filtered_df[['Product', 'Description', 'Pallet', 'Quantity', 'Location']]

filtered_df = filtered_df.sort_values(by='Product')

filtered_df.to_csv('checking_sheet.csv', index=False)

print('Checking list is saved')

filtered_df

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

product_list = df2['Product'].tolist()

batch_size = 10

num_batches = len(product_list) // batch_size

date = input("Enter the date: ")

result_df = pd.DataFrame()

for batch in range(num_batches + 1):
    start_idx = batch * batch_size
    end_idx = (batch + 1) * batch_size

    batch_products = product_list[start_idx:end_idx]

    filtered_df = df[df['Product'].isin(batch_products)]

    filtered_df = filtered_df[['Product', 'Description', 'Pallet', 'Quantity', 'Location']]

    result_df = pd.concat([result_df, filtered_df], ignore_index=True)

    if len(result_df) >= batch_size:
        break

result_df = result_df.sort_values(by='Product')

result_df.to_csv(f'checking_day_{date}.csv', index=False)

print(f'Checking sheet for day {date} is saved')

result_df
Enter the date: 3
Checking sheet for 3 is saved

2.4. Пустой список местоположений

Чтобы улучшить управление запасами и выявить несоответствия, я разработал скрипт Python, который создает пустой список местоположений. Этот список содержит все пустые места на складе, что позволяет сотрудникам перепроверить любые неуместные запасы или неправильное количество. Этот список служит основой для поддержания организованной планировки склада и обеспечения точного инвентарного учета. Обнаружение любых несоответствий и соответствующая настройка системы повышают эффективность и надежность, обеспечивая быстрое и точное обслуживание клиентов. Пустой список местоположений упрощает управление запасами, способствуя организованной и эффективной работе склада:

import pandas as pd

df = pd.read_csv('warehouse_stocks.csv', low_memory=False)
df['Location'] = df['Location'].str.strip()

occupied_locations = set(df['Location'])

rack_locations_df = pd.read_csv('dc_locations.csv')
rack_locations_df['Location'] = rack_locations_df['Location'].str.strip()

empty_locations_df = rack_locations_df[~rack_locations_df['Location'].isin(occupied_locations)]

csv_file = 'empty_locations.csv'
empty_locations_df.to_csv(csv_file, index=False)

print(f"The list of empty locations has been saved to {csv_file}.")

empty_locations_df

The list of empty locations has been saved to empty_locations.csv. 

3. Визуализация

3.1. Тепловая карта распределения акций

Сценарий создает визуализацию тепловой карты, чтобы проиллюстрировать распределение запасов на складе. Используя данные из файлов «warehouse_stocks.csv» и «rack_locations.csv», мы анализируем распределение товаров по разным зонам и номерам стеллажей. Тепловая карта дает подробный обзор, помогая менеджерам склада эффективно определять области с большим или низким количеством запасов.
Это графическое представление помогает в принятии решений, оптимизации складских помещений и оптимизации управления запасами. Тепловая карта помогает персоналу склада выявлять области с низким уровнем запасов, способствуя быстрому пополнению запасов и избегая проблем с затовариванием.

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

df = pd.read_csv('warehouse_stocks.csv', usecols=['Product', 'Description', 'Pallet', 'Quantity', 'Location'], low_memory=False)

df[['Zone', 'Rack_numbers', 'Location_numbers', 'Levels']] = df['Location'].str.extract(r'([A-Z])([A-Z])(\d{2})([A-H])')

df.drop('Location', axis=1, inplace=True)

df = df[['Product', 'Description', 'Pallet', 'Quantity', 'Zone', 'Rack_numbers', 'Location_numbers', 'Levels']]

df.to_csv('split_warehouse_stocks.csv', index=False)

print(f"The split_warehouse_stocks.csv has been saved")

df = pd.read_csv('split_warehouse_stocks.csv')

rack_locations_df = pd.read_csv('dc_locations.csv')

rack_locations_df[['Zone', 'Rack_numbers', 'Location_numbers', 'Levels']] = rack_locations_df['Location'].str.extract(r'([A-Z])([A-Z])(\d{2})([A-H])')

rack_locations_df['Location_numbers'] = rack_locations_df['Location_numbers'].astype(str)
df['Location_numbers'] = df['Location_numbers'].astype(str)

rack_stock = rack_locations_df.merge(df, how='left', on=['Zone', 'Rack_numbers', 'Location_numbers', 'Levels'])

grouped_stock = rack_stock.groupby(['Zone', 'Rack_numbers']).agg({'Product': lambda x: x.notnull().sum()}).reset_index()

heatmap_data = grouped_stock.pivot(index='Zone', columns='Rack_numbers', values='Product')

plt.figure(figsize=(10, 8))
sns.heatmap(heatmap_data, cmap='YlGnBu', annot=True, fmt='.0f', cbar_kws={'label': 'Count'})
plt.title('Stock Distribution Heatmap')
plt.xlabel('Rack Numbers')
plt.ylabel('Zone')
plt.tight_layout()
plt.show()

3.2. График активности

Представленная здесь диаграмма деятельности демонстрирует различные визуализации и анализы, связанные со сбором и получением товаров в распределительном центре. Данные собирались в течение пяти дней из нескольких файлов CSV. Основная цель — предоставить информацию об операциях по сбору и приемке, включая работу персонала, перемещение поддонов и трендовые продукты.

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

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

df_m = pd.read_csv('picking_1.csv', low_memory=False)
df_m.info()

df_m[['Zone', 'Rack_numbers', 'Location_numbers', 'Levels']] = df_m['Location'].str.extract(r'([A-Z])([A-Z])(\d{2})([A-H])')

df_m.drop('Location', axis=1, inplace=True)

df_m = df_m[['Product', 'Description', 'Pallet', 'Task', 'Staff', 'Quantity', 'Zone', 'Rack_numbers', 'Location_numbers', 'Levels']]

df_m.to_csv('split_picking_1.csv', index=False)

print("The split_picking_1.csv has been saved")

df = pd.read_csv('split_picking_1.csv')

rack_locations_df = pd.read_csv('dc_locations.csv')

rack_locations_df[['Zone', 'Rack_numbers', 'Location_numbers', 'Levels']] = rack_locations_df['Location'].str.extract(r'([A-Z])([A-Z])(\d{2})([A-H])')

rack_locations_df['Location_numbers'] = rack_locations_df['Location_numbers'].astype(str)
df['Location_numbers'] = df['Location_numbers'].astype(str)

rack_stock = rack_locations_df.merge(df, how='left', on=['Zone', 'Rack_numbers', 'Location_numbers', 'Levels'])

grouped_stock = rack_stock.groupby(['Zone', 'Rack_numbers']).agg({'Product': lambda x: x.notnull().sum()}).reset_index()

heatmap_data = grouped_stock.pivot(index='Zone', columns='Rack_numbers', values='Product')

plt.figure(figsize=(10, 8))
sns.heatmap(heatmap_data, cmap='YlGnBu', annot=True, fmt='.0f', cbar_kws={'label': 'Count'})
plt.title('Picking Heatmap')
plt.xlabel('Rack Numbers')
plt.ylabel('Zone')
plt.tight_layout()
plt.show()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 9056 entries, 0 to 9055
Data columns (total 14 columns):
 #   Column       Non-Null Count  Dtype 
---  ------       --------------  ----- 
 0   Product      9056 non-null   object
 1   Description  9056 non-null   object
 2   Category     9056 non-null   object
 3   Brand        9056 non-null   object
 4   Size         9056 non-null   object
 5   Function     9056 non-null   object
 6   Colour       9056 non-null   object
 7   Pallet       9056 non-null   object
 8   Quantity     9056 non-null   int64 
 9   Location     9056 non-null   object
 10  Staff        9056 non-null   object
 11  To           9056 non-null   object
 12  Customer     9056 non-null   int64 
 13  Task         9056 non-null   object
dtypes: int64(2), object(12)
memory usage: 990.6+ KB
The split_picking_1.csv has been saved

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

В третьем разделе рассматриваются ежедневные записи о сборе заказов персоналом. Данные из нескольких файлов CSV объединяются для создания всеобъемлющего набора данных. Используя линейный график, мы визуализируем, как количество линий, выбранных каждым сотрудником, меняется в течение пяти дней. Эта диаграмма помогает нам выявить закономерности или тенденции в продуктивности персонала за период наблюдения.

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import re

file_names = ['picking_1.csv', 'picking_2.csv', 'picking_3.csv', 'picking_4.csv', 'picking_5.csv']

all_data = pd.DataFrame()

for file_name in file_names:
    df = pd.read_csv(file_name)
    day = re.search(r'picking_(\d)\.csv', file_name).group(1)
    df['Day'] = day
    all_data = pd.concat([all_data, df])

pallets_moved_by_staff_and_day = all_data.groupby(['Staff', 'Day'])['Location'].nunique().reset_index()

pallets_moved_by_staff_and_day = pallets_moved_by_staff_and_day.sort_values(by=['Staff', 'Day'])

plt.figure(figsize=(12, 6))
sns.lineplot(x='Day', y='Location', hue='Staff', data=pallets_moved_by_staff_and_day, palette='viridis', marker='o')
plt.xlabel('Day')
plt.ylabel('Number of lines')
plt.title('Daily picking records by Staff')

plt.ylim(bottom=800)

plt.tight_layout()
plt.show()

Четвертый раздел смещает акцент на процесс размещения (получения). Как и в предыдущих разделах, данные загружаются из файла «receive_1.csv», а производительность персонала визуализируется с помощью гистограммы. На этой диаграмме показаны сотрудники, которые наиболее активно выполняли задачи по размещению, в зависимости от количества обработанных ими строк.

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

df = pd.read_csv('receiving_1.csv')

pallets_moved_by_staff = df.groupby('Staff')['Location'].nunique().reset_index()

pallets_moved_by_staff = pallets_moved_by_staff.sort_values(by='Location', ascending=False)

plt.figure(figsize=(10, 6))
sns.barplot(x='Staff', y='Location', data=pallets_moved_by_staff, palette='viridis')
plt.xlabel('Staff')
plt.ylabel('Number of line')
plt.title('Put away records by Staff')
plt.tight_layout()
plt.show()

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

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import re

file_names = ['receiving_1.csv', 'receiving_2.csv', 'receiving_3.csv', 'receiving_4.csv', 'receiving_5.csv']

all_data = pd.DataFrame()

for file_name in file_names:
    df = pd.read_csv(file_name)
    day = re.search(r'receiving_(\d)\.csv', file_name).group(1)
    df['Day'] = day
    all_data = pd.concat([all_data, df])

pallets_moved_by_staff_and_day = all_data.groupby(['Staff', 'Day'])['Location'].nunique().reset_index()

pallets_moved_by_staff_and_day = pallets_moved_by_staff_and_day.sort_values(by=['Staff', 'Day'])

plt.figure(figsize=(12, 6))
sns.lineplot(x='Day', y='Location', hue='Staff', data=pallets_moved_by_staff_and_day, palette='viridis', marker='o')
plt.xlabel('Day')
plt.ylabel('Number of lines')
plt.title('Daily put away records by Staff')

plt.ylim(bottom=1000)

plt.tight_layout()
plt.show()

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

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import re

file_names = ['picking_1.csv', 'picking_2.csv', 'picking_3.csv', 'picking_4.csv', 'picking_5.csv']

all_data = pd.DataFrame()

for file_name in file_names:
    df = pd.read_csv(file_name)
    day = re.search(r'picking_(\d)\.csv', file_name).group(1)
    df['Day'] = day
    all_data = pd.concat([all_data, df])

def extract_count(packsize):
    parts = packsize.split('*')
    count = np.prod([int(part) for part in parts])
    return count

all_data['Pallets_Picked'] = all_data['Quantity'] / all_data['Pallet'].apply(extract_count)

grouped_data = all_data.groupby(['Product', 'Day']).agg({'Quantity': 'sum', 'Pallets_Picked': 'sum'}).reset_index()

top_10_products = grouped_data.groupby('Product')['Quantity'].sum().nlargest(10).index

top_10_data = grouped_data[grouped_data['Product'].isin(top_10_products)]

plt.figure(figsize=(10, 6))
for product in top_10_products:
    product_data = top_10_data[top_10_data['Product'] == product]
    plt.plot(product_data['Day'], product_data['Pallets_Picked'], label=product)

plt.xlabel('Day')
plt.ylabel('Number of Pallets')
plt.title('Top 10 Trending Products Over 5 Days')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()

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

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import re

file_names = ['receiving_1.csv', 'receiving_2.csv', 'receiving_3.csv', 'receiving_4.csv', 'receiving_5.csv']

all_data = pd.DataFrame()

for file_name in file_names:
    df = pd.read_csv(file_name)
    day = re.search(r'receiving_(\d)\.csv', file_name).group(1)
    df['Day'] = day
    all_data = pd.concat([all_data, df])

def extract_count_receiving(packsize):
    parts = packsize.split('*')
    count = np.prod([int(part) for part in parts])
    return count

all_data['Pallets_Picked'] = all_data['Quantity'] / all_data['Pallet'].apply(extract_count_receiving)

top_10_products = grouped_data.groupby('Product')['Quantity'].sum().nlargest(10).index

top_10_data = grouped_data[grouped_data['Product'].isin(top_10_products)]

plt.figure(figsize=(10, 6))
for product in top_10_products:
    product_data = top_10_data[top_10_data['Product'] == product]
    plt.plot(product_data['Day'], product_data['Pallets_Picked'], label=product)

plt.xlabel('Day')
plt.ylabel('Number of Pallets')
plt.title('Top 10 Receiving Products Over 5 Days')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()

Наконец, в восьмом разделе собраны сведения как о процессах отбора, так и о приемке. Разница между количеством полученных и отобранных поддонов для 10 лучших продуктов рассчитывается и визуализируется с помощью линейного графика. Эта диаграмма помогает определить любые расхождения между двумя процессами для наиболее популярных продуктов.

import pandas as pd
import matplotlib.pyplot as plt
import re

file_names = ['picking_1.csv', 'picking_2.csv', 'picking_3.csv', 'picking_4.csv', 'picking_5.csv']

all_data = pd.DataFrame()

for file_name in file_names:
    df = pd.read_csv(file_name)
    day = re.search(r'picking_(\d)\.csv', file_name).group(1)
    df['Day'] = int(day)
    all_data = pd.concat([all_data, df])

def extract_count(packsize):
    parts = packsize.split('*')
    count = int(parts[0])
    return count

all_data['Pallets_Picked'] = all_data['Quantity'] / all_data['Pallet'].apply(extract_count)

grouped_data = all_data.groupby(['Product', 'Day']).agg({'Quantity': 'sum', 'Pallets_Picked': 'sum'}).reset_index()

top_10_products = grouped_data.groupby('Product')['Quantity'].sum().nlargest(10).index

top_10_data = grouped_data[grouped_data['Product'].isin(top_10_products)]

receiving_file_names = ['receiving_1.csv', 'receiving_2.csv', 'receiving_3.csv', 'receiving_4.csv', 'receiving_5.csv']

receiving_dfs = [pd.read_csv(file) for file in receiving_file_names]

receiving_df = pd.concat(receiving_dfs, ignore_index=True)

def extract_count_receiving(packsize):
    parts = packsize.split('*')
    count = np.prod([int(part) for part in parts])
    return count

receiving_df['Pallets_Received'] = receiving_df['Quantity'] / receiving_df['Pallet'].apply(extract_count_receiving)

receiving_top_10_data = receiving_df[receiving_df['Product'].isin(top_10_products)]

receiving_grouped_data = receiving_top_10_data.groupby('Product').agg({'Quantity': 'sum', 'Pallets_Received': 'sum'}).reset_index()

top_10_with_receiving = pd.merge(top_10_data, receiving_grouped_data, on='Product', how='left')

top_10_with_receiving['Variance'] = top_10_with_receiving['Pallets_Received'] - top_10_with_receiving['Pallets_Picked']

plt.figure(figsize=(10, 6))
for product in top_10_products:
    product_data = top_10_with_receiving[top_10_with_receiving['Product'] == product]
    plt.plot(product_data['Day'], product_data['Variance'], label=product)

plt.xlabel('Day')
plt.ylabel('Variance (Received - Picked) - Plt')
plt.title('Top 10 Trending Products: Variance between Receiving and Picking Over 5 Days')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()

4. Вывод

Анализ набора данных Mega Star Distribution Center дал ценную информацию о мире логистики и складирования. Когда мы исследовали набор данных, было сделано несколько ключевых выводов:

  1. Python как мощный инструмент. В ходе этого анализа Python показал себя универсальным и мощным инструментом для обработки обширных наборов данных. Обширные библиотеки Python, такие как Pandas, Seaborn и Matplotlib, от очистки и преобразования данных до расширенной аналитики и визуализации, позволили нам эффективно обрабатывать и анализировать данные.
  2. ИИ для решения проблем: интеграция инструментов искусственного интеллекта (ИИ) может значительно улучшить логистические и складские операции. Алгоритмы ИИ могут быстро обрабатывать большие объемы данных, выявлять закономерности и принимать решения на основе данных. Внедрение решений на основе ИИ может привести к оптимизации управления запасами, лучшему прогнозированию спроса и более эффективному планированию маршрутов.
  3. Принятие решений на основе данных. В век технологий принятие решений на основе данных имеет первостепенное значение. Анализ данных хранилища позволяет нам получать ценную информацию, выявлять узкие места и принимать обоснованные решения для оптимизации процессов. Использование аналитики данных позволяет компаниям опережать конкурентов и повышать качество обслуживания клиентов.
  4. Непрерывное совершенствование. Мир логистики и складского хозяйства постоянно развивается. Для компаний крайне важно внедрить культуру постоянного совершенствования. Используя возможности данных, автоматизации и инструментов на основе ИИ, предприятия могут оставаться гибкими и эффективно адаптироваться к изменяющимся требованиям рынка.
  5. Внедрение автоматизации. В сфере логистики и складского хозяйства наблюдается быстрый прогресс в области автоматизации. Автоматизированные системы, такие как робототехника и интеллектуальные машины, революционизируют способы управления запасами, обработки поставок и оптимизации складских площадей. Внедряя автоматизацию, компании могут повысить эффективность, сократить количество ошибок, совершаемых вручную, и оптимизировать операции.