pandas 在int型数组中,将每次重复出现的n替换为n和n+1之间的浮点数

2guxujil  于 2023-10-14  发布在  其他
关注(0)|答案(3)|浏览(84)

假设我有一个带有列a的df,看起来像这样:

a
-
1
2
2
3
3
3
3
2
4
4
5

我正在寻找一种有效的方法,通过将它们转换为中间浮点数来“消除重复”值。因此,预期输出可以是下面显示的两个输出之一

a          a
-          -
1          1
2.25       2
2.5        2.33333
3.2        3
3.4        3.25
3.6        3.5
3.8        3.75
2.75       2.66666
4.33333    4
4.66666    4.5
5          5

我唯一能想到的是在a上执行groupby,并在0到n之间放置一个np.linspace,其中n是该组的a的值。但我认为这是低效的。是否有更好、更快的方法来做到这一点?谢谢你,谢谢

4xrmg8kj

4xrmg8kj1#

使用groupby.cumcountgroupby.transform('size')

g = df.groupby('a')['a']
s = g.transform('size')
df['out'] = np.where(s>1, df['a']+g.cumcount().add(1)/s.add(1), s)

第二种方法:

g = df.groupby('a')['a']
df['out2'] = df['a']+g.cumcount()/g.transform('size')

输出量:

a       out      out2
0   1  1.000000  1.000000
1   2  2.250000  2.000000
2   2  2.500000  2.333333
3   3  3.200000  3.000000
4   3  3.400000  3.250000
5   3  3.600000  3.500000
6   3  3.800000  3.750000
7   2  2.750000  2.666667
8   4  4.333333  4.000000
9   4  4.666667  4.500000
10  5  1.000000  5.000000
e37o9pze

e37o9pze2#

您可以使用np.linspace来获得均匀间隔的数字:

df["a_new"] = df.groupby("a", sort=False, group_keys=False)["a"].transform(
    lambda s: np.linspace(0, 1, len(s), endpoint=False) + s.iat[0]
)
print(df)

图纸:

a     a_new
0   1  1.000000
1   2  2.000000
2   2  2.333333
3   3  3.000000
4   3  3.250000
5   3  3.500000
6   3  3.750000
7   2  2.666667
8   4  4.000000
9   4  4.500000
10  5  5.000000
kjthegm6

kjthegm63#

仅对重复序列应用均匀分布(np.random.uniform):

rng = np.random.default_rng()
(df.groupby('a')['a'].transform(lambda x: rng.uniform(x.name, x.name+1, x.size)
                                if x.size > 1 else x))
0     1.000000
1     2.328058
2     2.570871
3     3.116998
4     3.887849
5     3.353023
6     3.127169
7     2.810340
8     4.006301
9     4.435186
10    5.000000

相关问题