Python Pandas:将DataFrame组的最后一个值分配给该组的所有条目 [英] Python Pandas: Assign Last Value of DataFrame Group to All Entries of That Group

查看:1140
本文介绍了Python Pandas:将DataFrame组的最后一个值分配给该组的所有条目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Python Pandas中,我有一个DataFrame。我将这个DataFrame按列分组,并希望将列的最后一个值分配给另一列的所有行。



我知道我可以选择最后一行
$ b

 将pandas导入为pd 

df = pd.DataFrame({ 'a':(1,1,2,3,3),'b':( 20,21,30,40,41)})
print(df)
print( - )
result = df.groupby('a')。nth(-1)
print(result)

结果:

  ab 
0 1 20
1 1 21
2 2 30
3 3 40
4 3 41
-
b
a
1 21
2 30
3 41

如何将此操作的结果返回给原始数据框,以便我有如下所示:

  ab b_new 
0 1 20 21
1 1 21 21
2 2 30 30
3 3 40 41
4 3 41 41


解决方案

使用 transform last

  df ['b_new'] = df .groupby('a')['b']。transform('last')



  df ['b_new'] = df.groupby('a')['b']。transform(lambda x: x.iat [-1])$ ​​b 
$ b print(df)
ab b_new
0 1 20 21
1 1 21 21
2 2 30 30
3 3 40 41
4 3 41 41

nth > : .join(df.groupby('a')['b'] .nnth(-1).rename('b_new'),'a')
print(df)
ab b_new
0 1 20 21
1 1 21 21
2 2 30 30
3 3 40 41
4 3 41 41

定时

  N = 10000 

df = pd.DataFrame({'a':np.random.randint(1000,size = N),
'b':np.random.randint(10000,大小= N)})

#print(df)


def f(df):
return df.join(df.groupby( '''['b']。nth(-1).rename('b_new'),'a')

#cᴏʟᴅsᴘᴇᴇᴅ1
在[211]中:%timeit df [ 'b_new'] = df.a.map(df.groupby('a')。b.nth(-1))
100个循环,最好是3:每个循环3.57 ms

#cᴏʟᴅsᴘᴇᴇᴅ2
In [212]:%timeit df ['b_new'] = df.a.replace(df.groupby('a')。b.nth(-1))
10个循环,最好的3:每循环71.3毫秒

#jezrael1
In [213]:%timeit df ['b_new'] = df.groupby('a')['b']。transform('last')
1000个循环,最好的3:1.82 ms per loop

#jezrael2
In [214]:%timeit df ['b_new'] = df.groupby('a')['b']。transform( lambda x:x.iat [-1])$ ​​b $ b 10个循环,最好是3:每个循环178 ms

#jezrael3
在[219]中:%timeit f(df )
100个循环,最好是3:每循环3.63 ms

警告



考虑到组的数量,结果并未解决性能问题,这些解决方案会影响很多时间。


In Python Pandas, I have a DataFrame. I group this DataFrame by a column and want to assign the last value of a column to all rows of another column.

I know that I am able to select the last row of the group by this command:

import pandas as pd

df = pd.DataFrame({'a': (1,1,2,3,3), 'b':(20,21,30,40,41)})
print(df)
print("-")
result = df.groupby('a').nth(-1)
print(result)

Result:

   a   b
0  1  20
1  1  21
2  2  30
3  3  40
4  3  41
-
    b
a    
1  21
2  30
3  41

How would it be possible to assign the result of this operation back to the original dataframe so that I have something like:

   a   b b_new
0  1  20 21
1  1  21 21
2  2  30 30
3  3  40 41
4  3  41 41

解决方案

Use transform with last:

df['b_new'] = df.groupby('a')['b'].transform('last')

Alternative:

df['b_new'] = df.groupby('a')['b'].transform(lambda x: x.iat[-1])

print(df)
   a   b  b_new
0  1  20     21
1  1  21     21
2  2  30     30
3  3  40     41
4  3  41     41

Solution with nth and join:

df = df.join(df.groupby('a')['b'].nth(-1).rename('b_new'), 'a')
print(df)
   a   b  b_new
0  1  20     21
1  1  21     21
2  2  30     30
3  3  40     41
4  3  41     41

Timings:

N = 10000

df = pd.DataFrame({'a':np.random.randint(1000,size=N),
                   'b':np.random.randint(10000,size=N)})

#print (df)


def f(df):
    return df.join(df.groupby('a')['b'].nth(-1).rename('b_new'), 'a')

#cᴏʟᴅsᴘᴇᴇᴅ1
In [211]: %timeit df['b_new'] = df.a.map(df.groupby('a').b.nth(-1))
100 loops, best of 3: 3.57 ms per loop

#cᴏʟᴅsᴘᴇᴇᴅ2
In [212]: %timeit df['b_new'] = df.a.replace(df.groupby('a').b.nth(-1))
10 loops, best of 3: 71.3 ms per loop

#jezrael1
In [213]: %timeit df['b_new'] = df.groupby('a')['b'].transform('last')
1000 loops, best of 3: 1.82 ms per loop

#jezrael2
In [214]: %timeit df['b_new'] = df.groupby('a')['b'].transform(lambda x: x.iat[-1])
10 loops, best of 3: 178 ms per loop

#jezrael3
In [219]: %timeit f(df)
100 loops, best of 3: 3.63 ms per loop

Caveat

The results do not address performance given the number of groups, which will affect timings a lot for some of these solutions.

这篇关于Python Pandas:将DataFrame组的最后一个值分配给该组的所有条目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆