我是编码新手,我正在寻找一种 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/