2017-11-16 4 views
1

グループ内の値をシフトしたいが、シリーズ内のグループのサブセットのみをシフトしたい。パンダグループのサブセットのグループ内の値をシフト

は、私は次のシリーズのようなものがあります。

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 

が、私はそれがあるように、グループAがままにしておきたいのが、グループB及びCは、それらの値が1でシフトアップしている必要があります。 this質問で説明したように、次のように私は(すべてのグループ全体でこれを行うことができます。

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

をしかし、グループのサブセットのみのためにこれを行うために、私はシリーズを分離するよりも、よりエレガントな方法を考え出すことはできません私は以下を示して、その後、戻って一緒に連結する:

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 

はこれをよりエレガントな解決策はあります

答えて

2
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 

またはあなただけの特定の行(を更新することができますか?これは簡単に解を簡素化します:

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 
+1

df.loc [['B'、 'C​​']] = df.loc [['B'、 'C​​']] .groupby(level = 0).shift(-1) ' –

+0

@cᴏʟᴅsᴘᴇᴇᴅ、asnwerとして投稿してください! :-) – MaxU

+1

いいえ、解決策はあなたの派生品なので、あなたの投稿に属しています。 ;-) –

関連する問題