我想知道是否有一种简单的方法来仅获取数据帧中每个分组对象(例如对象ID)的第一行。这样做:
for index, row in df.iterrows():
# do stuff
给我们每一行,但是我对做这样的事情很感兴趣:
groups = df.groupby('Subject id')
for index, row in groups.iterrows():
# give me the first row of each group
continue
有没有一种pythonic的方法可以完成以上操作?
答案 0 :(得分:2)
.groupby()
-由.drop_duplicates()
您想要的是在特定列中仅保留首次出现的行:
df.drop_duplicates(subset='Subject id', keep='first')
在熊猫中使用.apply(func)
:
df.groupby('Subject id').apply(lambda df: df.iloc[0, :])
它对lambda
返回的数据帧列表中的每个数据帧应用一个函数(主要是由df.groupby()
即时生成),并将结果汇总到单个最终数据帧。
但是,@ AkshayNevrekar的解决方案非常适合.first()
。就像他在那儿所做的一样,您也可以将其附加在这里-最后是.reset_index()
。
让我们说这是更通用的解决方案-您也可以选择第n行...-但是,仅当所有子数据帧至少具有n行时,此方法才有效。 否则,请使用:
n = 3
col = 'Subject id'
res_df = pd.DataFrame()
for name, df in df.groupby(col):
if n < (df.shape[0]):
res_df = res_df.append(df.reset_index().iloc[n, :])
或作为功能:
def group_by_select_nth_row(df, col, n):
res_df = pd.DataFrame()
for name, df in df.groupby(col):
if n < df.shape[0]:
res_df = res_df.append(df.reset_index().iloc[n, :])
return res_df
非常令人困惑的是,与df.append()
相比,list.append()
仅返回附加值,而原始df
保持不变。
因此,如果您想进行“就地”添加,就应该始终重新分配它,就像list.append()
中使用的那样。
答案 1 :(得分:1)
使用first()
获取每个组的第一行。
df = pd.DataFrame({'subject_id': [1,1,2,2,2,3,4,4], 'val':[20,32,12,34,45,43,23,10]})
# print(df.groupby('subject_id').first().reset_index())
print(df.groupby('subject_id', as_index=False).first())
输出:
subject_id val
0 1 20
1 2 12
2 3 43
3 4 23