Python Pandas:将 DataFrame 组的最后一个值分配给该组的所有条目
Posted
技术标签:
【中文标题】Python Pandas:将 DataFrame 组的最后一个值分配给该组的所有条目【英文标题】:Python Pandas: Assign Last Value of DataFrame Group to All Entries of That Group 【发布时间】:2018-06-04 02:20:48 【问题描述】:在 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)
结果:
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
如何将此操作的结果分配回原始数据帧,以便我有类似的东西:
a b b_new
0 1 20 21
1 1 21 21
2 2 30 30
3 3 40 41
4 3 41 41
【问题讨论】:
【参考方案1】:将transform
与last
一起使用:
df['b_new'] = df.groupby('a')['b'].transform('last')
替代方案:
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
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
时间安排:
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
警告
考虑到组的数量,结果并未解决性能问题,这将对其中一些解决方案的时间产生很大影响。
【讨论】:
【参考方案2】:两种可能,groupby
+ nth
+ map
或 replace
df['b_new'] = df.a.map(df.groupby('a').b.nth(-1))
或者,
df['b_new'] = df.a.replace(df.groupby('a').b.nth(-1))
您也可以将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
【讨论】:
【参考方案3】:我认为这应该很快
df.merge(df.drop_duplicates('a',keep='last'),on='a',how='left')
Out[797]:
a b_x b_y
0 1 20 21
1 1 21 21
2 2 30 30
3 3 40 41
4 3 41 41
【讨论】:
以上是关于Python Pandas:将 DataFrame 组的最后一个值分配给该组的所有条目的主要内容,如果未能解决你的问题,请参考以下文章
python 将Numpy数组转换为Pandas Dataframe
python pandas中如何将dataframe中的一列字符串类型转换为浮点类型?
python 将Pandas Dataframe导出到csv(无索引)
python 将Pandas Dataframe导出到Excel文件中