在数据框中仅获取每个主题的第一行

时间:2019-06-10 11:05:27

标签: python pandas dataframe

我想知道是否有一种简单的方法来仅获取数据帧中每个分组对象(例如对象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的方法可以完成以上操作?

2 个答案:

答案 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