Как L oop через сгруппированный массив данных - PullRequest
0 голосов
/ 25 февраля 2020

Я супер-новичок в python, но углублюсь, чтобы попытаться выяснить реальную проблему, используя инструменты анализа, такие как pandas.

Я уже импортировал данные из csv , но вот небольшая копия данных:

df2 = pd.DataFrame({'SKU': [22335, 22335, 22335, 22335, 33442, 33442, 33442, 33442],
                'Date': ['2019-12-31', '2020-01-07', '2020-01-14', '2020-01-21', '2019-12-31', '2020-01-07', '2020-01-14', '2020-01-21'],
                'Urgent': [10,8,4,20,50,45,65,32],
                'Delivered': [4,7,12,10, 35,75,23,42]})

Есть два номера артикула, 22335 и 33442, недельная дата начала, еженедельные срочные запросы на оборудование и еженедельные количества доставленного оборудования. На данный момент я выяснил, как рассчитать для всего набора данных a для l oop, что для каждой строки ссылается на вычисленное значение предыдущей строки:

# Create new numeric column 'Result'
df['Result'] = np.nan

# Assign initial value for the first row of 'Result' (Should be first row in each SKU group)
df.loc[0, 'Result'] = df.loc[0, 'Delivered'] + df.loc[1, 'Delivered'] - df.loc[0, 'Urgent']

# Loop through each row except for last row to calculate
for i in range(1, len(df)-1):
    df.loc[i,'Result'] = max(df.loc[i-1, 'Result'], 0) + df.loc[i+1, 'Delivered'] - df.loc[i, 'Urgent']

print(df)

Однако следующий шаг для меня - это Выполните выше только для каждого отдельного SKU (22335, а затем 33442 отдельно). Я попытался ранжировать каждую строку по SKU по дате, используя groupby, но я не могу понять, как ссылаться на это в моем l oop:

# Convert Date datatype
df['Date'] = pd.to_datetime(df['Date'])

# Use groupby to create ranking by SKU and Date
df['SKURank'] = df.groupby('SKU')['Date'].rank(ascending = True).astype('int64')

Я безуспешно пытался определить функцию, которая может ссылаться на свой собственный вывод для каждой итерации, а затем вызывать его в стиле .apply l oop, но, если честно, я полностью потерян на этом.

Я также пытался соблюдать разделение , применить, объединить принцип и сгруппировать мои данные по SKU, применить l oop, а затем объединить все строки обратно, но опять же я действительно не знаю, с чего начать.

Вот мои основные вопросы :

Какой тип l oop следует использовать для выполнения той же задачи, что и код выше (вернуть начальное значение для первой строки в группе, а затем l oop через каждый последующий ряд) для каждой отдельной группы SKU?

Если рекомендуемая форма l oop (независимо от производительности, я еще не настолько высок), требует, чтобы я определил функцию заранее, как бы я создал функцию Ион, который ссылается на свой собственный вывод для каждой строки, следующей за первой строкой для каждого SKU?

ОБНОВЛЕНИЕ:

о боже. Боже мой, что я создал ... это ... это отвратительно ...

Да, я создал гиганта для l oop с вложенными операторами if. И да, это ужасно. И нет, он не делает все, что мне нужно, чтобы выполнить l oop в последнем ряду кадра данных. Если какая-либо часть из приведенного ниже имеет смысл, и вы можете указать мне, как сделать это действительно функциональным, я буду признателен за несколько советов.

import pandas as pd
import numpy as np

# Create dataframe for two SKUs, a weekly process date, urgent requested quantity, and delivered quantity
df = pd.DataFrame({'SKU': [22335, 22335, 22335, 22335, 33442, 33442, 33442, 33442],
                    'Date': ['2019-12-31', '2020-01-07', '2020-01-14', '2020-01-21', '2019-12-31', '2020-01-07', '2020-01-14', '2020-01-21'],
                    'Urgent': [10,8,4,20,50,45,65,32],
                    'Delivered': [4,7,12,10, 35,75,23,42]})

# Create new numeric column 'Result'
df['Result'] = np.nan

# Convert Date datatype and create 3 necessary columns
df['Date'] = pd.to_datetime(df['Date'])
df['Result'] = np.nan
df['WeeklyMiss'] = np.nan
df['Logic'] = ''

# Create list of unique SKUs in dataframe
skulst = df.SKU.unique()

print(skulst)


# Set initial indeces value 
skunum = 0
i = 0

# While loop with nested for loop to iterate over the dataframe
while skunum <= len(skulst):
    for i in range(0, len(df)-1):
        # Calculate first SKU row
        if i == 0 and df.loc[i, 'SKU'] == skulst[skunum]: 
            df.loc[i, 'Result'] = max(df.loc[i, 'Delivered'] + df.loc[i+1, 'Delivered'] - df.loc[i, 'Urgent'], 0)
            df.loc[i, 'WeeklyMiss'] = min(df.loc[i, 'Delivered'] + df.loc[i+1, 'Delivered'] - df.loc[i, 'Urgent'], 0)
            df.loc[i, 'Logic'] = 'First Row'
        # Calculate next SKU rows
        elif i > 0 and df.loc[i, 'SKU'] == skulst[skunum] and df.loc[i+1,'SKU'] == skulst[skunum]:
            df.loc[i, 'Result'] = max(df.loc[i+1, 'Delivered'] + min(df.loc[i-1, 'Result'], df.loc[i, 'Delivered']) - df.loc[i, 'Urgent'], 0)
            df.loc[i, 'WeeklyMiss'] = min(df.loc[i-1, 'Result'] + df.loc[i+1, 'Delivered'] - df.loc[i, 'Urgent'], 0)
            df.loc[i, 'Logic'] = 'Next SKU Row'
        # Calculate last SKU row
        elif i > 0 and df.loc[i, 'SKU'] == skulst[skunum] and (df.loc[i+1,'SKU'] != skulst[skunum] or i == len(df)):
            df.loc[i, 'Result'] = max(df.loc[i-1, 'Result'] - df.loc[i, 'Urgent'], 0)
            df.loc[i, 'WeeklyMiss'] = min(df.loc[i-1, 'Result'] - df.loc[i, 'Urgent'], 0)
            df.loc[i, 'Logic'] = 'Last SKU Row'


        # Calculate first SKU row and switch to next SKU 
        elif i > 0 and i < len(df) and df.loc[i, 'SKU'] != skulst[skunum] and df.loc[i-1,'SKU'] == skulst[skunum] :
            df.loc[i, 'Result'] = max(df.loc[i, 'Delivered'] + df.loc[i+1, 'Delivered'] - df.loc[i, 'Urgent'], 0)
            df.loc[i, 'WeeklyMiss'] = min(df.loc[i, 'Delivered'] + df.loc[i+1, 'Delivered'] - df.loc[i, 'Urgent'], 0)
            df.loc[i, 'Logic'] = 'First SKU Row'
            if skunum + 1 <= len(skulst):
                skunum += 1
            else:
                df.loc[i, 'Result'] = max(df.loc[i-1, 'Result'] - df.loc[i, 'Urgent'], 0)
                df.loc[i, 'WeeklyMiss'] = min(df.loc[i-1, 'Result'] - df.loc[i, 'Urgent'], 0)
                df.loc[i, 'Logic'] = 'Last SKU Row'
                continue
    else:
        print(df)
        break

1 Ответ

0 голосов
/ 25 февраля 2020

См. Руководство по Group By: split-apply-объединить из pandas документации, чтобы узнать, как можно перебирать группы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...