我是编码新手,我正在寻找一种 Pythonic 方式来实现以下代码。这是一个带有代码的示例数据框:

np.random.seed(1111)
df2 = pd.DataFrame({
'Product':np.random.choice( ['Prod 1','Prod 2','Prod 3', 'Prod 4','Prod 5','Prod 6','Box 1','Box 2','Box 3'], 10000),
'Transaction_Type': np.random.choice(['Produced','Transferred','Scrapped','Sold'], 10000),
'Quantity':np.random.randint(1,100, size=(10000)),
'Date':np.random.choice( pd.date_range('1/1/2017','12/31/2018',
                      freq='D'), 10000)})
idx = pd.IndexSlice

在数据集中,每个'Box'('Box 1'、'Box 2'等)都是一个原 Material ,对应多个产品。例如,“Box 1”用于“Prod 1”和“Prod 2”,“Box 2”用于“Prod 3”和“Prod 4”,“Box 3”用于“Prod 5”& '产品 6'。

我使用的数据集要大得多,但我将这些数据集存储为列表,例如我有“Box 1” = ['Prod 1', 'Prod 2', 'Prod 3']。如果需要,我可以将像 Box1 = {'Box 1':('Prod 1','Prod 2') 这样的元组存储为字典 - 无论是最好的。

对于每个分组,我希望计算使用的箱子总数,即“生产”+“报废”库存的总和。为了获得这个值,我目前正在对每个产品的 groupby 进行手动过滤并手动过滤。您可以看到我正在手动编写产品列表作为第二个分配语句。

例如,要计算每个月要从库存中减少多少“Box 1”,您可以将生产和报废的“Box 1”的值相加。然后,您将计算生产和报废的“Prod 1”到“Prod 3”(因为它们使用“Box 1”)的值,并将它们加在一起得到每次使用和报废的“Box 1”总数框架。这是我目前正在做的一个例子:
box1 = ['Box 1','Prod 1','Prod 2']
df2[df2['Transaction_Type'].isin(['Produced','Scrapped'])].groupby([pd.Grouper(key='Date',freq='A' ),'Product','Transaction_Type']).agg({'Quantity':'sum'})\
    .unstack()\
    .loc[idx[:,box1],idx[:]]\
    .assign(Box_1 = lambda x: 'Box 1')\
    .assign(List_of_Products = lambda x: 'Box 1, Prod 1, Prod 2')\
    .reset_index()\
    .set_index(['Box_1','List_of_Products','Date','Product'])\
    .groupby(level=[0,1,2]).sum()\

然后我必须为“Box 2”等做同样笨重的手动练习。

有没有更pythonic的方式?我想以后每个月都完成这个分析。实际数据要复杂得多,大约有 20 个不同的“盒子”,每个盒子都有不同数量的产品。我不确定我是否应该创建一个函数或使用字典与列表,但希望得到任何帮助。作为最后一个请求,我希望能够灵活地将这些“Box_1”中的每一个写入不同的 Excel 工作表。

提前致谢!

最佳答案

不确定最后你想要的结果如何,但由于每个 Prod 只使用一个 Box ,那么你可以通过 replace Prod Box 并像你一样做 groupby 。假设您有一本字典,例如:

box_dict = {'Box 1': ('Prod 1', 'Prod 2'),
            'Box 2': ('Prod 3', 'Prod 4'),
            'Box 3': ('Prod 5', 'Prod 6')}

那么你想反转它以获得 prod 作为键和 box 作为值:
dict_prod = { prod:box for box, l_prod in box_dict.items() for prod in l_prod}

现在您可以使用 replace :
print (df2[df2['Transaction_Type'].isin(['Produced','Scrapped'])]
          .replace({'Product':dict_prod}) #here to change the prod to the box used
          .groupby([pd.Grouper(key='Date',freq='A' ),'Product','Transaction_Type'])['Quantity']
          .sum().unstack())
                    Quantity
Transaction_Type   Produced Scrapped
Date       Product
2017-12-31 Box 1      20450    19152
           Box 2      20848    21145
           Box 3      22475    21518
2018-12-31 Box 1      19404    16964
           Box 2      21655    20753
           Box 3      21343    21576

关于python - Pandas - 遍历列表/字典进行计算,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53822977/

10-16 03:12