假设我有一个如下所示的数据框:
[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的value列中的值将从116变为114。 d,e,f,g从225升至222。
请指教。
答案 0 :(得分:5)
使用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
答案 1 :(得分:3)
如果连续的值是唯一的,则可以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
答案 2 :(得分:3)
使用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
答案 3 :(得分:2)
可能会有更清洁的方法来执行此操作,但是您可以像这样获得所需的结果:
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
的结果,该结果只是一个{{ 1}}对象,即每个连续组的长度(即从第一组减去range
,从第二组减去0
,依此类推...)
答案 4 :(得分:0)
我认为首先您必须对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.