Pandas:通过 groupby 对象迭代填充缺失值
Pandas: filling missing values iterating through a groupby object
我有以下数据集:
d = {'player': ['1', '1', '1', '1', '1', '1', '1', '1', '1', '2', '2',
'2', '2', '2', '2', '3', '3', '3', '3', '3'],
'session': ['a', 'a', 'b', np.nan, 'b', 'c', 'c', 'c', 'c', 'd', 'd',
'e', 'e', np.nan, 'e', 'f', 'f', 'g', np.nan, 'g'],
'date': ['2018-01-01 00:19:05', '2018-01-01 00:21:07',
'2018-01-01 00:22:07', '2018-01-01 00:22:15','2018-01-01 00:25:09',
'2018-01-01 00:25:11', '2018-01-01 00:27:28', '2018-01-01 00:29:29',
'2018-01-01 00:30:35', '2018-01-01 00:21:16', '2018-01-01 00:35:22',
'2018-01-01 00:38:16', '2018-01-01 00:38:20', '2018-01-01 00:40:35',
'2018-01-01 01:31:16', '2018-01-03 00:55:22', '2018-01-03 00:58:16',
'2018-01-03 00:58:21', '2018-03-01 01:00:35', '2018-03-01 01:31:16']
}
#create dataframe
df = pd.DataFrame(data=d)
#change date to datetime
df['date'] = pd.to_datetime(df['date'])
df.head()
player session date
0 1 a 2018-01-01 00:19:05
1 1 a 2018-01-01 00:21:07
2 1 b 2018-01-01 00:22:07
3 1 NaN 2018-01-01 00:22:15
4 1 b 2018-01-01 00:25:09
所以,这是我的三个专栏:
- 'player' - 三个玩家 (1,2,3) - dtype = object
- 'session'(对象)。每个会话 ID 将玩家在线实施的一组动作(即数据集中的行)组合在一起。
- 'date'(日期时间对象)告诉我们每个动作执行的时间。
这个数据集中的问题是我有每个动作的时间戳,但有些动作缺少它们的会话 ID。我想要做的是:对于每个玩家,我想根据时间轴为缺失值提供一个 id 标签。如果缺少 id 的动作落在特定会话的时间范围内(第一个动作 - 最后一个动作),则可以对其进行标记。
假设我按玩家和 ID 分组,并计算每个会话的时间范围:
my_agg = df.groupby(['player', 'session']).date.agg([min, max])
my_agg
min max
player session
1 a 2018-01-01 00:19:05 2018-01-01 00:21:07
b 2018-01-01 00:22:07 2018-01-01 00:25:09
c 2018-01-01 00:25:11 2018-01-01 00:30:35
2 d 2018-01-01 00:21:16 2018-01-01 00:35:22
e 2018-01-01 00:38:16 2018-01-01 01:31:16
3 f 2018-01-03 00:55:22 2018-01-03 00:58:16
g 2018-01-03 00:58:21 2018-03-01 01:31:16
此时我想遍历每个玩家,并逐个会话比较我的 nan 值的时间戳,看看它们属于哪里。
期望输出:在例子中,第一个Nan应该被标记为'b',第二个被标记为'e',最后一个为'g'。
免责声明:我前几天问过类似的问题,得到了很好的回答,但这次我必须考虑到另一个变量和我又卡住了。确实,Python 中的第一步令人兴奋,但也非常具有挑战性。
您的示例已经排序,但是即使您的输入未排序,这也应该会产生您想要的结果。如果此答案不满足您的要求,请 post 一个额外的(或修改过的)示例数据框,其中包含预期的输出,这确实违反了您的要求。
df.sort_values(['player','date']).fillna(method='ffill')
产量:
player session date
0 1 a 2018-01-01 00:19:05
1 1 a 2018-01-01 00:21:07
2 1 b 2018-01-01 00:22:07
3 1 b 2018-01-01 00:22:15
4 1 b 2018-01-01 00:25:09
5 1 c 2018-01-01 00:25:11
6 1 c 2018-01-01 00:27:28
7 1 c 2018-01-01 00:29:29
8 1 c 2018-01-01 00:30:35
9 2 d 2018-01-01 00:21:16
10 2 d 2018-01-01 00:35:22
11 2 e 2018-01-01 00:38:16
12 2 e 2018-01-01 00:38:20
13 2 e 2018-01-01 00:40:35
14 2 e 2018-01-01 01:31:16
15 3 f 2018-01-03 00:55:22
16 3 f 2018-01-03 00:58:16
17 3 g 2018-01-03 00:58:21
18 3 g 2018-03-01 01:00:35
19 3 g 2018-03-01 01:31:16
我有以下数据集:
d = {'player': ['1', '1', '1', '1', '1', '1', '1', '1', '1', '2', '2',
'2', '2', '2', '2', '3', '3', '3', '3', '3'],
'session': ['a', 'a', 'b', np.nan, 'b', 'c', 'c', 'c', 'c', 'd', 'd',
'e', 'e', np.nan, 'e', 'f', 'f', 'g', np.nan, 'g'],
'date': ['2018-01-01 00:19:05', '2018-01-01 00:21:07',
'2018-01-01 00:22:07', '2018-01-01 00:22:15','2018-01-01 00:25:09',
'2018-01-01 00:25:11', '2018-01-01 00:27:28', '2018-01-01 00:29:29',
'2018-01-01 00:30:35', '2018-01-01 00:21:16', '2018-01-01 00:35:22',
'2018-01-01 00:38:16', '2018-01-01 00:38:20', '2018-01-01 00:40:35',
'2018-01-01 01:31:16', '2018-01-03 00:55:22', '2018-01-03 00:58:16',
'2018-01-03 00:58:21', '2018-03-01 01:00:35', '2018-03-01 01:31:16']
}
#create dataframe
df = pd.DataFrame(data=d)
#change date to datetime
df['date'] = pd.to_datetime(df['date'])
df.head()
player session date
0 1 a 2018-01-01 00:19:05
1 1 a 2018-01-01 00:21:07
2 1 b 2018-01-01 00:22:07
3 1 NaN 2018-01-01 00:22:15
4 1 b 2018-01-01 00:25:09
所以,这是我的三个专栏:
- 'player' - 三个玩家 (1,2,3) - dtype = object
- 'session'(对象)。每个会话 ID 将玩家在线实施的一组动作(即数据集中的行)组合在一起。
- 'date'(日期时间对象)告诉我们每个动作执行的时间。
这个数据集中的问题是我有每个动作的时间戳,但有些动作缺少它们的会话 ID。我想要做的是:对于每个玩家,我想根据时间轴为缺失值提供一个 id 标签。如果缺少 id 的动作落在特定会话的时间范围内(第一个动作 - 最后一个动作),则可以对其进行标记。
假设我按玩家和 ID 分组,并计算每个会话的时间范围:
my_agg = df.groupby(['player', 'session']).date.agg([min, max])
my_agg
min max
player session
1 a 2018-01-01 00:19:05 2018-01-01 00:21:07
b 2018-01-01 00:22:07 2018-01-01 00:25:09
c 2018-01-01 00:25:11 2018-01-01 00:30:35
2 d 2018-01-01 00:21:16 2018-01-01 00:35:22
e 2018-01-01 00:38:16 2018-01-01 01:31:16
3 f 2018-01-03 00:55:22 2018-01-03 00:58:16
g 2018-01-03 00:58:21 2018-03-01 01:31:16
此时我想遍历每个玩家,并逐个会话比较我的 nan 值的时间戳,看看它们属于哪里。
期望输出:在例子中,第一个Nan应该被标记为'b',第二个被标记为'e',最后一个为'g'。
免责声明:我前几天问过类似的问题
您的示例已经排序,但是即使您的输入未排序,这也应该会产生您想要的结果。如果此答案不满足您的要求,请 post 一个额外的(或修改过的)示例数据框,其中包含预期的输出,这确实违反了您的要求。
df.sort_values(['player','date']).fillna(method='ffill')
产量:
player session date
0 1 a 2018-01-01 00:19:05
1 1 a 2018-01-01 00:21:07
2 1 b 2018-01-01 00:22:07
3 1 b 2018-01-01 00:22:15
4 1 b 2018-01-01 00:25:09
5 1 c 2018-01-01 00:25:11
6 1 c 2018-01-01 00:27:28
7 1 c 2018-01-01 00:29:29
8 1 c 2018-01-01 00:30:35
9 2 d 2018-01-01 00:21:16
10 2 d 2018-01-01 00:35:22
11 2 e 2018-01-01 00:38:16
12 2 e 2018-01-01 00:38:20
13 2 e 2018-01-01 00:40:35
14 2 e 2018-01-01 01:31:16
15 3 f 2018-01-03 00:55:22
16 3 f 2018-01-03 00:58:16
17 3 g 2018-01-03 00:58:21
18 3 g 2018-03-01 01:00:35
19 3 g 2018-03-01 01:31:16