简体   繁体   English

组内子集的Pandas Shift值

[英]Pandas Shift values within group for subset of groups

I am looking to shift values within group, but only for a subset of the groups in the Series. 我希望在组内移动值,但仅针对系列中组的子集。

I have something like the following Series: 我有类似以下系列的内容:

import pandas as pd
df=pd.DataFrame()
df['Group']=['A','A','A','B','B','B','C','C','C']
df['Month']=[1,2,3,1,2,3,1,2,3]
df['Value']=1000,900,800,700,600,500,400,300,200
df=df.set_index(['Group','Month'])['Value']
df
Out[101]: 
Group  Month
A      1        1000
       2         900
       3         800
B      1         700
       2         600
       3         500
C      1         400
       2         300
       3         200
Name: Value, dtype: int64

I want group A to remain as it is, but groups B and C should have their values shifted up by one. 我希望A组保持原样,但B和C组的值应上移一个。 I can do this across all groups (as described in this question as follows: 我可以在所有组中执行此操作(如以下问题中所述:

 df.groupby(level='Group').transform(lambda x:x.shift(-1))

However, to do this for only a subset of groups, I can't come up with a more elegant way than separating the series and then concatenating back together, as I show below: 但是,仅对一组子集执行此操作,我无法想出比将系列分离然后再连接在一起的更优雅的方法,如下所示:

df_a = df[df.index.get_level_values('Group')=='A']
df_other = df[df.index.get_level_values('Group')<>'A']

pd.concat([df_a,df_other.groupby(level='Group').transform(lambda x:x.shift(-1))])
Out[104]: 
Group  Month
A      1        1000.0
       2         900.0
       3         800.0
B      1         600.0
       2         500.0
       3           NaN
C      1         300.0
       2         200.0
       3           NaN
Name: Value, dtype: float64

Is there a more elegant solution to this? 有没有更优雅的解决方案?

In [361]: df.groupby(level='Group').transform(lambda x:x if x.name=='A' else x.shift(-1))
Out[361]:
Group  Month
A      1        1000.0
       2         900.0
       3         800.0
B      1         600.0
       2         500.0
       3           NaN
C      1         300.0
       2         200.0
       3           NaN
Name: Value, dtype: float64

or you can update only specific rows ( solution provided by @cᴏʟᴅsᴘᴇᴇᴅ ) - this will simplify solution dramatically: 或者您可以只更新特定的行( @cᴏʟᴅsᴘᴇᴇᴅ提供的解决方案 )-这将大大简化解决方案:

In [363]: df.loc[['B', 'C']] = df.loc[['B', 'C']].groupby(level=0).shift(-1)

In [364]: df
Out[364]:
Group  Month
A      1        1000.0
       2         900.0
       3         800.0
B      1         600.0
       2         500.0
       3           NaN
C      1         300.0
       2         200.0
       3           NaN
Name: Value, dtype: float64

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM