如何使用 pandas 减去数据集中所有列的分组数据中的第一个和最后一个值

How to subtract first and last values in grouped data for all columns in dataset using pandas

我有一个时间序列数据集,其中包含患者抑郁、焦虑和创伤量表的分数。在每个患者的 6 个时间点收集数据。

mh_data.head(10)
ID    BDI   GAD   TSQ  age
1     57     9     4    22
1     36     9     4    22
1     37     9     4    22
1     38     7     3    22
1     41     8     3    22
1     39     7     3    22
2     29     14    7    35
2     27     12    6    35
2     27     11    6    35
2     23     11    3    35

我想创建一个新数据集,其中每个患者的每个变量只有 1 个对应值,代表第一个最后一个数据点和记录的数据点之间的差异。所以,它看起来像这样:

ID    BDI   GAD   TSQ  age
1     18     2     1    22
2     1      0     2    35
.     .      .     .    .
.     .      .     .    .
.     .      .     .    .

我已将数据分组并按第一个和最后一个分数汇总:

mhs_agg = mhs_data.groupby("ID").agg(['first','last']) 

我该如何继续或有更有效的方法吗?我也有年龄,这是一个我不想计算差异的变量(因为这对每个人来说都是 0)。

我看过以下所有帖子,none 的建议似乎适用于我的具体情况。

How to apply "first" and "last" functions to columns while using group by in pandas?

Python/Pandas - Aggregating dataframe with first/last function without grouping

Pandas DataFrame groupby two columns and get first and last

尝试:

df1 = df[['ID','BDI', 'GAD', 'TSQ']].groupby('ID').agg('first')-df[['ID','BDI', 'GAD', 'TSQ']].groupby('ID').agg('last')
df_final = df1.merge(df[['ID','age']].groupby('ID').agg('first'), on='ID')


    BDI  GAD  TSQ  age
ID
1    18    2    1   22
2     6    3    4   35

第二个选项使用 lambda 获取第一部分,然后合并

df[['ID','BDI', 'GAD', 'TSQ']].groupby('ID', as_index=False).apply(lambda x: x.groupby('ID').agg('first')-x.groupby('ID').agg('last'))

您可以将任意函数传递给 .agg()。当你这样做时,你的函数一次接收每个 pandas 系列 1,已经过滤到一个单独的“组”。

我可能会将整个计算作为一个函数进行,而不是多个单独的步骤ps。

import pandas as pd

my_data = pd.DataFrame(
    {'id': [1, 1, 1, 2, 2, 2], 
     'b': [0, 2, 5, 2, 4, 8],
     'c': [5, 8, 1, 4, 2, 1]})

def diff_calc(x):
    x1 = x[:1].values # Get first value
    x2 = x[-1:].values # Get last value
    
    return abs(x1 - x2)

my_data.groupby('id').agg(diff_calc)

输入

id b c
1 0 5
1 2 8
1 5 1
2 2 4
2 4 2
2 8 1

输出

id b c
1 5 4
2 6 3

ps:您可能想在最后使用 .reset_index(),因为 pandas groupBy 有点奇怪,这可能是您最初遇到的问题 运行 成.

这应该有效:

df.groupby('ID').agg(lambda x: x.iloc[0] - x.iloc[-1])