在Pandas中,创建一个相对于组内特定类别的变量
In Pandas, create a variable relative to a specific category within the group
我有一个这样的数据框
df = pd.DataFrame({'week': [1, 1, 1, 2, 2, 2, 3, 3, 3],
'p': list(range(1, 4)) * 3,
'q': [4, 2, 1, 6, 2, 1, 6, 3, 2]})
df
week p q
0 1 1 4
1 1 2 2
2 1 3 1
3 2 1 6
4 2 2 2
5 2 3 1
6 3 1 6
7 3 2 3
8 3 3 2
在此数据框中,p 标识产品(1、2 和 3),q 是一周内的销售量。我需要用一周内的信息创建两个变量。第一个应具有 q 相对于 p=3 的乘积的比率。第二个应该具有相对于产品 2(对于产品 1)和相对于产品 3(对于产品 2)的比率。所需的输出应为:
week p q d1 d2
0 1 1 4 4.0 2.0
1 1 2 2 2.0 2.0
2 1 3 1 1.0 1.0
3 2 1 6 6.0 3.0
4 2 2 2 2.0 2.0
5 2 3 1 1.0 1.0
6 3 1 6 3.0 2.0
7 3 2 3 1.5 1.5
8 3 3 2 1.0 1.0
答案是相关的,它允许我创建第一个变量(我需要用产品 p = 3 的 NaN 替换)。
df['d1']=np.nan
df['d1']=df.loc[df.p!=3,'d1'].\
fillna(df.q/df.groupby('week').q.transform('last'))
df
week p q d1
0 1 1 4 4.0
1 1 2 2 2.0
2 1 3 1 NaN
3 2 1 6 6.0
4 2 2 2 2.0
5 2 3 1 NaN
6 3 1 6 3.0
7 3 2 3 1.5
8 3 3 2 NaN
还有两件事我没弄清楚。首先,如果不是相对于 p=3 定义第一个变量,而是相对于 p=2 定义它,我将如何修改上面的代码? (或者什么替代方案会更好?)
其次,如何生成第二个变量? (对于 p=1,q 的值相对于 p=2,对于 p=2,q 的值相对于 p=3)。
试试这个:
df['d1'] = df.q / df.q.where(df.p.eq(3)).groupby(df.week).transform('first')
df['d2'] = df.q / df.groupby('week').q.shift(-1).fillna(df.q)
Out[74]:
week p q d1 d2
0 1 1 4 4.0 2.0
1 1 2 2 2.0 2.0
2 1 3 1 1.0 1.0
3 2 1 6 6.0 3.0
4 2 2 2 2.0 2.0
5 2 3 1 1.0 1.0
6 3 1 6 3.0 2.0
7 3 2 3 1.5 1.5
8 3 3 2 1.0 1.0
我有一个这样的数据框
df = pd.DataFrame({'week': [1, 1, 1, 2, 2, 2, 3, 3, 3],
'p': list(range(1, 4)) * 3,
'q': [4, 2, 1, 6, 2, 1, 6, 3, 2]})
df
week p q
0 1 1 4
1 1 2 2
2 1 3 1
3 2 1 6
4 2 2 2
5 2 3 1
6 3 1 6
7 3 2 3
8 3 3 2
在此数据框中,p 标识产品(1、2 和 3),q 是一周内的销售量。我需要用一周内的信息创建两个变量。第一个应具有 q 相对于 p=3 的乘积的比率。第二个应该具有相对于产品 2(对于产品 1)和相对于产品 3(对于产品 2)的比率。所需的输出应为:
week p q d1 d2
0 1 1 4 4.0 2.0
1 1 2 2 2.0 2.0
2 1 3 1 1.0 1.0
3 2 1 6 6.0 3.0
4 2 2 2 2.0 2.0
5 2 3 1 1.0 1.0
6 3 1 6 3.0 2.0
7 3 2 3 1.5 1.5
8 3 3 2 1.0 1.0
df['d1']=np.nan
df['d1']=df.loc[df.p!=3,'d1'].\
fillna(df.q/df.groupby('week').q.transform('last'))
df
week p q d1
0 1 1 4 4.0
1 1 2 2 2.0
2 1 3 1 NaN
3 2 1 6 6.0
4 2 2 2 2.0
5 2 3 1 NaN
6 3 1 6 3.0
7 3 2 3 1.5
8 3 3 2 NaN
还有两件事我没弄清楚。首先,如果不是相对于 p=3 定义第一个变量,而是相对于 p=2 定义它,我将如何修改上面的代码? (或者什么替代方案会更好?)
其次,如何生成第二个变量? (对于 p=1,q 的值相对于 p=2,对于 p=2,q 的值相对于 p=3)。
试试这个:
df['d1'] = df.q / df.q.where(df.p.eq(3)).groupby(df.week).transform('first')
df['d2'] = df.q / df.groupby('week').q.shift(-1).fillna(df.q)
Out[74]:
week p q d1 d2
0 1 1 4 4.0 2.0
1 1 2 2 2.0 2.0
2 1 3 1 1.0 1.0
3 2 1 6 6.0 3.0
4 2 2 2 2.0 2.0
5 2 3 1 1.0 1.0
6 3 1 6 3.0 2.0
7 3 2 3 1.5 1.5
8 3 3 2 1.0 1.0