Python Pandas:获取DataFrame分组ID首尾记录,单条记录需重复输出
解决DataFrame中获取各ID首次/末次记录(含单次出现ID重复输出)的问题
我明白你的需求:需要提取DataFrame中每个ID的首次和末次出现记录,对于只出现一次的ID,要把这条记录同时作为首次和末次记录输出两次。你尝试用data.groupby('ID', as_index=False).nth([0,-1])但遇到了问题——仅出现一次的ID(比如示例中的B)只输出了一次,不符合预期。
先看示例数据构造
首先我们还原你的示例数据:
import pandas as pd data = pd.DataFrame({ 'ID': ['A', 'A', 'A', 'B', 'C', 'C'], 'Date': ['1/1/2015', '1/5/2016', '1/3/2017', '1/3/2017', '1/5/2016', '1/7/2016'] })
问题原因
你使用的nth([0,-1])方法,当组内只有一条记录时,0和-1指向的是同一个位置,pandas会自动去重,所以只会保留一条记录,这就是为什么ID=B只出现一次的原因。
解决方案1:结合head()和tail()合并结果
这个方法思路很直接:分别获取每个ID的首次记录(head(1))和末次记录(tail(1)),然后将两个结果合并,最后按ID排序即可。对于单条记录的组,head和tail都会返回同一条记录,合并后就会出现两次,正好符合需求。
# 获取每个ID的首次出现记录 first_entries = data.groupby('ID', as_index=False).head(1) # 获取每个ID的末次出现记录 last_entries = data.groupby('ID', as_index=False).tail(1) # 合并两个结果并按ID排序,重置索引 final_result = pd.concat([first_entries, last_entries]).sort_values('ID').reset_index(drop=True)
执行后输出的结果如下,完全符合你的期望:
ID Date 0 A 1/1/2015 1 A 1/3/2017 2 B 1/3/2017 3 B 1/3/2017 4 C 1/5/2016 5 C 1/7/2016
解决方案2:自定义分组处理函数
如果你更倾向于用分组后自定义逻辑的方式,可以写一个函数来处理每个分组:当分组长度为1时,重复该记录;否则取首尾两条记录。
def process_group(group): # 如果组内只有一条记录,返回两次该记录 if len(group) == 1: return pd.concat([group, group]) # 否则返回首尾两条记录 else: return group.iloc[[0, -1]] # 应用自定义函数到每个分组 final_result = data.groupby('ID', as_index=False).apply(process_group).reset_index(drop=True)
这个方法也能得到和上面完全一致的结果,适合需要更灵活分组逻辑的场景。
内容的提问来源于stack exchange,提问作者user2552108
相关产品推荐
相关产品推荐

