У меня есть следующий датафрейм
0 0 0
1 0 0
1 1 0
1 1 1
1 1 1
0 0 0
0 1 0
0 1 0
0 0 0
как вы получаете датафрейм, который выглядит следующим образом
0 0 0
4 0 0
4 3 0
4 3 2
4 3 2
0 0 0
0 2 0
0 2 0
0 0 0
Спасибо за помощь.
Вам может понадобиться, используя цикл здесь, с tranform
, и используя cumsum
создать ключ и назначить позицию обратно к исходному ДФУ
for x in df.columns:
df.loc[df[x]!=0,x]=df[x].groupby(df[x].eq(0).cumsum()[df[x]!=0]).transform('count')
df
Out[229]:
1 2 3
0 0.0 0.0 0.0
1 4.0 0.0 0.0
2 4.0 3.0 0.0
3 4.0 3.0 2.0
4 4.0 3.0 2.0
5 0.0 0.0 0.0
6 0.0 2.0 0.0
7 0.0 2.0 0.0
8 0.0 0.0 0.0
Или без циклы
s=df.stack().sort_index(level=1)
s2=s.groupby([s.index.get_level_values(1),s.eq(0).cumsum()]).transform('count').sub(1).unstack()
df=df.mask(df!=0).combine_first(s2)
df
Out[255]:
1 2 3
0 0.0 0.0 0.0
1 4.0 0.0 0.0
2 4.0 3.0 0.0
3 4.0 3.0 2.0
4 4.0 3.0 2.0
5 0.0 0.0 0.0
6 0.0 2.0 0.0
7 0.0 2.0 0.0
8 0.0 0.0 0.0
Вот способ:
m = (df != df.shift(1)).cumsum()
df2 = pd.concat([df.iloc[:,i].groupby(m.iloc[:,i]).transform('size')
for i in range(df.shape[1])], axis=1)
pd.DataFrame(np.where(df==1,df2, df))
0 1 2
0 4 0 0
1 4 3 0
2 4 3 2
3 4 3 2
4 0 0 0
5 0 2 0
6 0 2 0
7 0 0 0
Куда:
(df != df.shift(1)).cumsum()
0 0.1 0.2
0 1 1 1
1 1 2 1
2 1 2 2
3 1 2 2
4 2 3 3
5 2 4 3
6 2 4 3
7 2 5 3
Который затем используется для группировки фрейма данных и получения size
:
0 0.1 0.2
0 4 1 2
1 4 3 2
2 4 3 2
3 4 3 2
4 4 1 4
5 4 2 4
6 4 2 4
7 4 1 4
Наконец, вы можете использовать np.where
для замены тех значений, где df == 1
:
pd.DataFrame(np.where(df==1,df2, df))
0 1 2
0 4 0 0
1 4 3 0
2 4 3 2
3 4 3 2
4 0 0 0
5 0 2 0
6 0 2 0
7 0 0 0