gpt4 book ai didi

python - Pandas 在不同数量的行中为每个 ID 选择三行

转载 作者:行者123 更新时间:2023-12-03 07:50:42 25 4
gpt4 key购买 nike

我有一个包含 100 多人的数据集,这些人经过不同时间的跟踪(每人最多 8 次观察)并完成了一系列测试。每个 ID 的时间值始终采用整数序列。我的项目的目标是检查个体的这些变化,同时从每个人的所有可用数据中以 3 个等间隔的间隔对每个人的数据进行采样。这是数据集的快照,为简洁起见,仅进行了两个测试。

    dict = {
"ID": [1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4],
"Time": [1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5, 1, 2],
"AlBa": [5, 2, 1, 8, 7, 6, 5, 9, 7, 6, 4, 2, 3, 1],
"Tiri": [4, 3, 2, 10, 9, 5, 4, 5, 4, 3, 2, 1, 4, 4]
}

df_test = pd.DataFrame(dict)
print(df_test)

ID Time AlBa Tiri
0 1 1 5 4
1 1 2 2 3
2 1 3 1 2
3 2 1 8 10
4 2 2 7 9
5 2 3 6 5
6 2 4 5 4
7 3 1 9 5
8 3 2 7 4
9 3 3 6 3
10 3 4 4 2
11 3 5 2 1
12 4 1 3 4
13 4 2 1 4

我想从每个人的所有可用数据中以 3 个等间隔的间隔对他们的数据进行采样,从而为每个 ID 提供三个数据点。因此,ID1 被包含在内,因为它们恰好有三个观察值。 ID 4 被排除,因为他们只有两个观察值。对于具有超过 3 个但奇数个观察值(例如 ID3)的个体,我想保留其第一次(时间 1)、最后一次(此处为时间 5)和中间观察(此处为时间 3)的分数。对于具有超过三个但偶数个观察值(例如 ID2)的个体,我想保留他们的第一个(时间 1)、最后一个(此处为时间 4),并找到中间两个观察值的平均值(此处, 2 次和 3 次的平均值)。最终的数据集应如下所示:

   ID  Time  AlBa Tiri
0 1 1.0 5.0 4
1 1 2.0 2.0 3
2 1 3.0 1.0 2
3 2 1.0 8.0 10
4 2 2.5 6.5 7
5 2 4.0 5.0 4
6 3 1.0 9.0 5
7 3 3.0 6.0 3
8 3 5.0 2.0 1

在 Pandas 中编码的最佳方法是什么?我拥有每人 1 到 8 个观察值的数据。

最佳答案

使用每组聚合 ( groupby.agg ) 和 first/median/last,然后使用 groupby.size 过滤 ID ,并用 stack reshape :

g = df_test.groupby('ID')
s = g.size()

out = (g.agg(['first', 'median', 'last'])
.loc[lambda d: s[s>2].index] # remove groups with < 2 values
.stack().reset_index()
#.drop(columns=['level_1'])
)

请注意,中位数取排序值的中点,如果您想要按位置计算中点,请使用自定义函数:

def mid_point(s):
return s.iloc[(len(s)-1)//2:len(s)//2+1].mean()

g = df_test.groupby('ID')
s = g.size()
out = (g.agg(['first', mid_point, 'last'])
.loc[lambda d: s[s>2].index]
.stack().reset_index()
)

输出:

   ID level_1  Time  AlBa  Tiri
0 1 first 1.0 5.0 4.0
1 1 median 2.0 2.0 3.0
2 1 last 3.0 1.0 2.0
3 2 first 1.0 8.0 10.0
4 2 median 2.5 6.5 7.0
5 2 last 4.0 5.0 4.0
6 3 first 1.0 9.0 5.0
7 3 median 3.0 6.0 3.0
8 3 last 5.0 2.0 1.0

正如 @Lahcen 在评论中指出的,您还可以在 groupby.agg 之前进行预过滤:

out = (df_test[df_test.groupby('ID')['ID'].transform('count').gt(2)]
.groupby('ID').agg(['first', 'median', 'last'])
.stack().reset_index().drop(columns=['level_1'])
)

区别在于,在一种情况下,您重用groupby对象(速度更快),但在计算后进行过滤(速度更慢)。在这种替代方案中,您必须计算groupby两次,但避免不必要的聚合。最佳方法可能取决于组的数量以及值少于 3 个的组的比例。用真实数据进行测试。

关于python - Pandas 在不同数量的行中为每个 ID 选择三行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77200529/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com