Python Pandas:将DataFrame Group的最后一个值分配给该组的所有条目

13 python group-by dataframe pandas pandas-groupby

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

我知道我可以通过此命令选择组的最后一行:

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)
Run Code Online (Sandbox Code Playgroud)

结果:

   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
Run Code Online (Sandbox Code Playgroud)

如何将此操作的结果分配回原始数据帧,以便我有类似的东西:

   a   b b_new
0  1  20 21
1  1  21 21
2  2  30 30
3  3  40 41
4  3  41 41
Run Code Online (Sandbox Code Playgroud)

jez*_*ael 7

使用transformlast:

df['b_new'] = df.groupby('a')['b'].transform('last')
Run Code Online (Sandbox Code Playgroud)

替代方案:

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
Run Code Online (Sandbox Code Playgroud)

nth和解决方案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
Run Code Online (Sandbox Code Playgroud)

时间:

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
Run Code Online (Sandbox Code Playgroud)

警告

考虑到组的数量,结果不能解决性能问题,这将对某些解决方案的时序产生很大影响.


cs9*_*s95 6

两种可能性,groupby+ nth+ mapreplace

df['b_new'] = df.a.map(df.groupby('a').b.nth(-1))
Run Code Online (Sandbox Code Playgroud)

要么,

df['b_new'] = df.a.replace(df.groupby('a').b.nth(-1))
Run Code Online (Sandbox Code Playgroud)

您也可以替换nth(-1)last()(事实上,这样做会发生,使这个快一点),但nth让你在什么项目,从各组中挑选更多的灵活性b.


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
Run Code Online (Sandbox Code Playgroud)