努力遍历数据帧

时间:2020-10-19 21:24:26

标签: python dataframe loops element

我是Python的新手,在将其发布到此处寻求帮助之前,我已尽我所能竭尽全力。我花了整整一个周末和一天的时间,试图提出我认为应该使用两个数据帧进行编码的简单场景,但是,对于我一生来说,我一直在转动轮子,没有取得任何重大进展。

情况是有一个包含销售数据的数据框:

CUSTOMER  ORDER   SALES_DATE  SALES_ITEM_NUMBER  UNIT_PRICE  SALES_QTY
001871    225404  01/31/2018  03266465555        1           200
001871    225643  02/02/2018  03266465555        2           600
001871    225655  02/02/2018  03266465555        3           1000
001956    228901  05/29/2018  03266461234        2.2658      20

和带有购买数据的第二个数据框:

PO_DATE       PO_ITEM_NUMBER  PO_QTY  PO_PRICE
01/15/2017    03266465555     1000    1.55
01/25/2017    03266465555     500     5.55
02/01/2017    03266461234     700     4.44
02/01/2017    03266461234     700     2.22

我要做的就是找出“销售订单”数据框上每一行的最大PO_PRICE可能是多少,因为我正试图最大程度地增加购买价与购买价之间的差异卖了。

当我第一次看这个时,我发现一个简单的嵌套for循环可以解决问题,并增加计数器。不过,问题在于我对数据帧不熟悉,因此我一直挂在尝试访问其中的元素的机会。同样要记住的是,我已经卖出了1800件第一件商品,但是只买了1500件。因此,当我遍历此内容时:

对于第一行销售订单,我卖出了200。Max_PO_PRICE= $ 5.55(其中有500个)。因此,我需要从PO_QTY数据框中减去200,因为我现在已经考虑了它们。

对于第二个销售订单行,我卖出了600。我仍然可以说我以5.55美元的价格买了300,但是,那500我已经用光了,所以最好的办法是浸入另一行的Max_PO_PRICE = $ 1.55(对于其中的1,000行)。因此,对于这一个,我可以以$ 5.55的价格要求300,而其他可以$ 1.55的价格要求$ 300。我不能索要的钱比买的多。

这是我想出的代码,我想我可能全都错了,但是,一些指导和建议将是难以置信的赞赏和帮助。

我并不是要任何人为我编写代码,而是只是建议您采用哪种方法,以及是否有更好的方法。我认为必须有...。

在此先感谢您的反馈和帮助。
-克莱尔

for index1,row1 in sales.iterrows():
    SalesQty = sales.loc[index1]["SALES_QTY"]
    for index2,row2 in purchases.iterrows():
        if (row1['SALES_ITEM_NUMBER']==row2['PO_ITEM_NUMBER']) and (row2['PO_QTY']>0):
           # Find the Maximum PO Price in the result set
               max_PO_Price = abc["PO_PRICE"].max()

            xyz = purchases.loc[index2]
            abc = abc.append(xyz)
    
           if(SalesQty <= Purchase_Qty):
              print("Before decrement, PO_QTY = ",??????? *<==== this is where I'm struggle busing****)
              print()
    +index2
    #Drop the data from the xyz DataFrame
    xyz=xyz.iloc[0:0]

    #Drop the data from the abc DataFrame
    abc=abc.iloc[0:0]
+index1

1 个答案:

答案 0 :(得分:1)

这看起来像SQL可以通过解析函数很好地处理的东西。幸运的是,Pandas具有大多数(但不是全部)此功能,并且比嵌套嵌套要快得多。无论如何,我都不是熊猫专家,但我会给他一个毛病。抱歉,如果我误解了这个问题。

合理地将SALES_QTY分组,我们将使用它来跟踪我们拥有多少数量:

sales_grouped = sales.groupby(["SALES_ITEM_NUMBER"], as_index = False).agg({"SALES_QTY":"sum"})

让我们将表分组为一个,以便我们可以迭代一个表而不是两个表。我们可以在公用列JOIN"PO_ITEM_NUMBER"上使用"SALES_ITEM_NUMBER"动作,也可以将Pandas称为“合并”。现在,让我们对按"PO_ITEM_NUMBER"分类的表进行排序,并在表的最顶部使用最昂贵的“ PO_PRICE”,这是下一个代码块,它等效于FN OVER PARTITION BY ORDER BY SQL分析函数。

sorted_table = purchases.merge(sales_grouped, 
                            how = "left",
                            left_on = "PO_ITEM_NUMBER",
                            right_on = "SALES_ITEM_NUMBER").sort_values(by = ["PO_ITEM_NUMBER", "PO_PRICE"], 
                                                                        ascending = False)

让我们创建一个列CUM_PO_QTY,其中包含PO_QTY的累积总和(由PO_ITEM_NUMBER划分/分组)。当我们超过最大SALES_QTY时,我们将使用它来标记。

sorted_table["CUM_PO_QTY"] = sorted_table.groupby(["PO_ITEM_NUMBER"], as_index = False)["PO_QTY"].cumsum()

这是自定义部分的来源,我们可以集成自定义函数,以使用apply()沿数据帧逐行(甚至逐列)应用。我们正在创建两列TRACKED_QTY,它们就是SALES_QTY减去CUM_PO_QTY,所以我们知道何时遇到负数,PRICE_SUM最终将是最大值获得或花费。但是现在:如果TRACKED_QTY小于0,则我们将PO_QTY乘以SALES_QTY进行保护。

sorted_table[["TRACKED_QTY", "PRICE_SUM"]] = sorted_table.apply(lambda x: pd.Series([x["SALES_QTY"] - x["CUM_PO_QTY"], 
                                                                              x["PO_QTY"] * x["PO_PRICE"] 
                                                                              if x["SALES_QTY"] - x["CUM_PO_QTY"] >= 0 
                                                                              else x["SALES_QTY"] * x["PO_PRICE"]]), axis = 1)

要处理尾随的TRACKED_QTY底片,我们可以使用条件掩码过滤正片,而groupby底片只显示最大PRICE_SUM值。 然后只需追加这两个表并将它们相加即可。

  evaluated_table = sorted_table[sorted_table["TRACKED_QTY"] >= 0]
evaluated_table = evaluated_table.append(sorted_table[sorted_table["TRACKED_QTY"] < 0].groupby(["PO_ITEM_NUMBER"], as_index = False).max())

    evaluated_table = evaluated_table.groupby(["PO_ITEM_NUMBER"], as_index = False).agg({"PRICE_SUM":"sum"})

希望这对您有用。