基于子集的DataFrame算法

时间:2018-09-11 11:43:23

标签: python pandas

具有类似于以下内容的数据框:

Country Column1 Product Week        Val
UK      S1      A       2019-36     10
UK      S1      A       2019-37     20
UK      S1      A       2019-38     30
UK      S1      B       2019-36     30
UK      S1      B       2019-37     30
UK      S1      B       2019-38     30
DE      S1      A       2019-39     100
DE      S1      A       2019-40     100
DE      S1      A       2019-41     100
DE      S1      B       2019-36     10
DE      S1      B       2019-37     15
DE      S1      B       2019-38     10

如何说: 如果Product =“ B”,则从产品“ A”中获取所有其他列相同的VAL(国家,列1和周),并将该Val的50%添加到当前值?

例如第一个“ B”的值为35:

30 + (50%*10)

第二个40:

30 + (50%*20)

和第三个45:

30 + (50%*30)

2 个答案:

答案 0 :(得分:1)

在“国家/地区”,“专栏1”和“周”上使用pd.Groupby两次(条件是在专栏2上)似乎有效:

B = df[df['Column2']=='B'].groupby(['Country','Column1','Week']).sum()
A = df[df['Column2']=='A'].groupby(['Country','Column1','Week']).sum() 
0.5*A + B

输出

                          Val
Country Column1 Week         
DE      S1      2019-36   NaN
                2019-37   NaN
                2019-38   NaN
                2019-39   NaN
                2019-40   NaN
                2019-41   NaN
UK      S1      2019-36  35.0
                2019-37  40.0
                2019-38  45.0
  

仅当“国家/地区”,“列1”和“星期”中的每个选项都有唯一值时,此方法才有效

答案 1 :(得分:0)

如何处理索引?

假设您将数据存储在名为pandas.DataFrame的{​​{1}}中

data

我认为这种方法的优势在于,它可以完全满足您的需求并就地实现结果。它产生

data = data.set_index(["Country", "Column1", "Week", "Product"], drop=False)
df1 = data[data.Product == "A"].set_index(["Country", "Column1", "Week"], drop=False)
df2 = data[data.Product == "B"].set_index(["Country", "Column1", "Week"], drop=False)
df2.Val += df1.Val * .5  # so that rows with all else the same would add
df2 = df2.set_index(["Country", "Column1", "Week", "Product"])
data.update(df2)
data["Index"] = range(len(data.Val))
data = data.set_index("Index")
data.index.name = None