pandas 具有后续匹配值索引的 Dataframe 列,包括从最终索引到初始索引的范围回绕方向

1l5u6lss  于 2023-01-28  发布在  其他
关注(0)|答案(2)|浏览(101)

如何创建具有特定值的后续索引的Dataframe列?我知道我可以使用查找匹配索引

b_Index = df[df.Type=='B'].index
c_Index = df[df.Type=='C'].index

但是我需要一个解决方案,它包括了回绕的情况,使得最终匹配之后的“下一个”索引是第一个索引。
假设我有一个Type系列的 Dataframe 。Type包含值A、B或C。

d = dict(Type=['A', 'A', 'A', 'C', 'C', 'C', 'A', 'A', 'C', 'A', 'B', 'B', 'B', 'A'])
df = pd.DataFrame(d)
   Type
0     A
1     A
2     A
3     C
4     C
5     C
6     A
7     A
8     C
9     A
10    B
11    B
12    B
13    A

我希望将NextForwardBIndexNextForwardCIndex列相加,结果为

Type  NextForwardBIndex  NextForwardCIndex
0     A                 10                  3
1     A                 10                  3
2     A                 10                  3
3     C                 10                  4
4     C                 10                  5
5     C                 10                  8
6     A                 10                  8
7     A                 10                  8
8     C                 10                  3
9     A                 10                  3
10    B                 11                  3
11    B                 12                  3
12    B                 10                  3
13    A                 10                  3
wmvff8tz

wmvff8tz1#

您可以使用一点numpy.rollpandas.ffillpandas.fillna

# roll indices and assign the next values for B/C rows
df.loc[b_Index, 'NextForwardBIndex'] = np.roll(b_Index,-1)
df.loc[c_Index, 'NextForwardCIndex'] = np.roll(c_Index,-1)
# fill missing values
(df.ffill()
   .fillna({'NextForwardBIndex': b_Index[0],
            'NextForwardCIndex': c_Index[0]})
   .astype(int, errors='ignore')
)

输出:

Type  NextForwardBIndex  NextForwardCIndex
0     A                 10                  3
1     A                 10                  3
2     A                 10                  3
3     C                  4                  4
4     C                  5                  5
5     C                  8                  8
6     A                  8                  8
7     A                  8                  8
8     C                  3                  3
9     A                  3                  3
10    B                 11                  3
11    B                 12                  3
12    B                 10                  3
13    A                 10                  3
gopyfrb3

gopyfrb32#

这应该行得通:

df2 = df['Type'].str.get_dummies().mul(s.index,axis=0).shift(-1).where(lambda x: x.ne(0)).bfill()

df2.fillna(df2.iloc[0]).rename('NextForward{}Index'.format,axis=1)

旧答案:

(df.assign(NextForwardBIndex = df.loc[df['Type'].eq('B')].groupby(df['Type']).transform(lambda x: x.index.to_series().shift(-1)),
         NextForwardCIndex = df.loc[df['Type'].eq('C')].groupby(df['Type']).transform(lambda x: x.index.to_series().shift(-1)))
 .fillna({'NextForwardBIndex':df['Type'].eq('B').idxmax(),'NextForwardCIndex':df['Type'].eq('C').idxmax()}))

输出:

NextForwardAIndex  NextForwardBIndex  NextForwardCIndex
0                 1.0               10.0                3.0
1                 2.0               10.0                3.0
2                 6.0               10.0                3.0
3                 6.0               10.0                4.0
4                 6.0               10.0                5.0
5                 6.0               10.0                8.0
6                 7.0               10.0                8.0
7                 9.0               10.0                8.0
8                 9.0               10.0                3.0
9                13.0               10.0                3.0
10               13.0               11.0                3.0
11               13.0               12.0                3.0
12               13.0               10.0                3.0
13                1.0               10.0                3.0

相关问题