如何从pandas dataframe的列中逐渐减少值

bhmjp9jg  于 2023-03-21  发布在  其他
关注(0)|答案(6)|浏览(202)

假设我有一个dataframe,如下所示:

[1] df
    name   value
     a      116
     b      116
     c      116
     d      225
     e      225
     f      225
     g      225

现在我希望df变成

name   value
     a      116
     b      115
     c      114
     d      225
     e      224
     f      223
     g      222

也就是说,如果原始df在连续行的一列中具有相同的(固定)值,则它应该以1的方式递减。因此,名称a、b、c的值列中的值从116变为114。d、e、f、g的值列中的值从225变为222。
善意的建议。

7d7tgy0s

7d7tgy0s1#

使用GroupBy.cumcount对连续值进行计数,并从value列中减去:

#consecutive rows to Series g
g = df['value'].ne(df['value'].shift()).cumsum()
df['value'] = df['value'] - df.groupby(g).cumcount()
print (df)
  name  value
0    a    116
1    b    115
2    c    114
3    d    225
4    e    224
5    f    223
6    g    222
5cg8jx4n

5cg8jx4n2#

如果连续值是唯一的,则可以transform

df.groupby('value').value.transform(lambda k: k - k.reset_index().index)

0    116
1    115
2    114
3    225
4    224
5    223
6    222
4uqofj5v

4uqofj5v3#

使用cumcount

df.value-=df.groupby('value').cumcount()
df
Out[215]: 
  name  value
0    a    116
1    b    115
2    c    114
3    d    225
4    e    224
5    f    223
6    g    222
mcdcgff0

mcdcgff04#

可能有一种更简洁的方法来做到这一点,但你可以像这样得到你想要的结果:

df['value'] = (df.assign(x = df.value.diff().ne(0).cumsum())
               .groupby('x')
               .value
               .transform(lambda y: y - y.reset_index().index))
>>> df
  name  value
0    a    116
1    b    115
2    c    114
3    d    225
4    e    224
5    f    223
6    g    222

本质上,这创建了一个列,它标记了连续的相等数量的块(我称之为x),按该列分组,然后减去reset_index的结果,这只是一个range对象,每个连续组的长度(即从第一个减去0,从第二个减去1,等等...)

g52tjvyc

g52tjvyc5#

我认为首先你必须对你的dataframe值列进行排序,然后你可以使用一个简单的for循环来减少值。

dataframe = dataframe.sort_values('value')                  #sort column 'value' 
j=0
for i in range(len(dataframe.index)-1):
    if(dataframe.iloc[i, 1] == dataframe.iloc[i+1,1]):            #if ith row value is equal to i+1th row value
        dataframe.iloc[i,1] = dataframe.iloc[i,1] - j             #then decrease 
        j = j + 1

    elif(dataframe.iloc[i, 1] != dataframe.iloc[i+1,1]):          # if not then decrease ith row value and again start with
        dataframe.iloc[i,1] = dataframe.iloc[i,1] - j             # j=0
        j=0

#print(j)                                                          
#print(i)
if(dataframe.iloc[i+1,1] == dataframe.iloc[i-j+1,1]):           # for last row check whether it is repeatation of original value
    dataframe.iloc[i+1,1] = dataframe.iloc[i+1,1] - j           # or not, if it is then decrease it.
xdnvmnnf

xdnvmnnf6#

def function1(dd:pd.DataFrame):
    dd1=dd.assign(col2=1)
    return dd.assign(value=dd1.col2.cumsum().mul(-1).add(1).add(dd1['value']))

col1=df1['value'].diff().ne(0).cumsum()
df1.groupby(col1).apply(function1)

输出:

name  value
0    a    116
1    b    115
2    c    114
3    d    225
4    e    224
5    f    223
6    g    222

相关问题