Pandas 根据另一列的日期时间值填充一列的缺失值
Pandas fill missing values of a column based on the datetime values of another column
Python新手,这是我的第一个问题。
我试图找到类似 SO 问题的解决方案,例如 , , and also ,但我认为我的问题有所不同。
这是我的情况:我有一个非常大的数据集,包含两列:Date(日期时间对象)和 session_id (整数)。时间戳指的是在线会话期间某个动作发生的时刻。
我的问题是我有所有日期,但缺少一些相应的 session_id 值。我想做的是使用日期列填充这些缺失值:
- 如果操作发生在某个会话的第一个日期和最后一个日期之间,我想用那个会话的 ID 填充缺失值。
- 我会将操作发生在任何会话范围之外的会话标记为“0”-
- 如果无法将事件关联到单个会话,则将其标记为'-99',因为它发生在不同会话的时间范围内。
为了举例说明我的问题,让我们考虑下面的玩具数据集,其中我只有三个会话:a、b、c。会话 a 和 b 注册了三个事件,会话 c 两个。此外,我缺少三个 id 值。
| DATE |sess_id|
----------------------------------
0 | 2018-01-01 00:19:01 | a |
1 | 2018-01-01 00:19:05 | b |
2 | 2018-01-01 00:21:07 | a |
3 | 2018-01-01 00:22:07 | b |
4 | 2018-01-01 00:25:09 | c |
5 | 2018-01-01 00:25:11 | Nan |
6 | 2018-01-01 00:27:28 | c |
7 | 2018-01-01 00:29:29 | a |
8 | 2018-01-01 00:30:35 | Nan |
9 | 2018-01-01 00:31:16 | b |
10 | 2018-01-01 00:35:22 | Nan |
...
[Image_Timeline example][1]
这是我想要得到的:
| DATE |sess_id|
----------------------------------
0 | 2018-01-01 00:19:01 | a |
1 | 2018-01-01 00:19:05 | b |
2 | 2018-01-01 00:21:07 | a |
3 | 2018-01-01 00:22:07 | b |
4 | 2018-01-01 00:25:09 | c |
5 | 2018-01-01 00:25:11 | -99 |
6 | 2018-01-01 00:27:28 | c |
7 | 2018-01-01 00:29:29 | a |
8 | 2018-01-01 00:30:35 | b |
9 | 2018-01-01 00:31:16 | b |
10 | 2018-01-01 00:35:22 | 0 |
...
通过这种方式,我将能够在没有会话代码的情况下至少恢复一些事件。
我认为也许要做的第一件事是计算两个新列,显示每个会话的第一个和最后一个时间值,类似这样:
foo['last'] = foo.groupby('sess_id')['DATE'].transform(max)
foo['firs'] = foo.groupby('SESSIONCODE')['DATE'].transform(min)
然后使用first-last时间值来检查每个session id未知的事件是否在该范围内。
你的直觉对我来说似乎很好,但你不能以这种方式应用它,因为你的数据框 foo
的大小与你的 groupby
数据框的大小不同。您可以做的是像这样映射值:
foo['last'] = foo.sess_id.map(foo.groupby('sess_id').DATE.max())
foo['first'] = foo.sess_id.map(foo.groupby('sess_id').DATE.min())
但我认为没有必要,您可以直接使用 groupby 数据框。
解决您的问题的一种方法是在 sess_id
列中查找缺失值,并将自定义函数应用于相应的日期:
def my_custom_function(time):
current_sessions = my_agg.loc[(my_agg['min']<time) & (my_agg['max']>time)]
count = len(current_sessions)
if count == 0:
return 0
if count > 1:
return -99
return current_sessions.index[0]
my_agg = foo.groupby('sess_id').DATE.agg([min,max])
foo.loc[foo.sess_id.isnull(),'sess_id'] = foo.loc[foo.sess_id.isnull(),'DATE'].apply(my_custom_function)
输出:
DATE sess_id
0 2018-01-01 00:19:01 a
1 2018-01-01 00:19:05 b
2 2018-01-01 00:21:07 a
3 2018-01-01 00:22:07 b
4 2018-01-01 00:25:09 c
5 2018-01-01 00:25:11 -99
6 2018-01-01 00:27:28 c
7 2018-01-01 00:29:29 a
8 2018-01-01 00:30:35 b
9 2018-01-01 00:31:16 b
10 2018-01-01 00:35:22 0
我认为它执行了您正在寻找的内容,尽管您在问题中发布的输出似乎包含拼写错误。
Python新手,这是我的第一个问题。
我试图找到类似 SO 问题的解决方案,例如
这是我的情况:我有一个非常大的数据集,包含两列:Date(日期时间对象)和 session_id (整数)。时间戳指的是在线会话期间某个动作发生的时刻。
我的问题是我有所有日期,但缺少一些相应的 session_id 值。我想做的是使用日期列填充这些缺失值:
- 如果操作发生在某个会话的第一个日期和最后一个日期之间,我想用那个会话的 ID 填充缺失值。
- 我会将操作发生在任何会话范围之外的会话标记为“0”-
- 如果无法将事件关联到单个会话,则将其标记为'-99',因为它发生在不同会话的时间范围内。
为了举例说明我的问题,让我们考虑下面的玩具数据集,其中我只有三个会话:a、b、c。会话 a 和 b 注册了三个事件,会话 c 两个。此外,我缺少三个 id 值。
| DATE |sess_id|
----------------------------------
0 | 2018-01-01 00:19:01 | a |
1 | 2018-01-01 00:19:05 | b |
2 | 2018-01-01 00:21:07 | a |
3 | 2018-01-01 00:22:07 | b |
4 | 2018-01-01 00:25:09 | c |
5 | 2018-01-01 00:25:11 | Nan |
6 | 2018-01-01 00:27:28 | c |
7 | 2018-01-01 00:29:29 | a |
8 | 2018-01-01 00:30:35 | Nan |
9 | 2018-01-01 00:31:16 | b |
10 | 2018-01-01 00:35:22 | Nan |
...
[Image_Timeline example][1]
这是我想要得到的:
| DATE |sess_id|
----------------------------------
0 | 2018-01-01 00:19:01 | a |
1 | 2018-01-01 00:19:05 | b |
2 | 2018-01-01 00:21:07 | a |
3 | 2018-01-01 00:22:07 | b |
4 | 2018-01-01 00:25:09 | c |
5 | 2018-01-01 00:25:11 | -99 |
6 | 2018-01-01 00:27:28 | c |
7 | 2018-01-01 00:29:29 | a |
8 | 2018-01-01 00:30:35 | b |
9 | 2018-01-01 00:31:16 | b |
10 | 2018-01-01 00:35:22 | 0 |
...
通过这种方式,我将能够在没有会话代码的情况下至少恢复一些事件。 我认为也许要做的第一件事是计算两个新列,显示每个会话的第一个和最后一个时间值,类似这样:
foo['last'] = foo.groupby('sess_id')['DATE'].transform(max)
foo['firs'] = foo.groupby('SESSIONCODE')['DATE'].transform(min)
然后使用first-last时间值来检查每个session id未知的事件是否在该范围内。
你的直觉对我来说似乎很好,但你不能以这种方式应用它,因为你的数据框 foo
的大小与你的 groupby
数据框的大小不同。您可以做的是像这样映射值:
foo['last'] = foo.sess_id.map(foo.groupby('sess_id').DATE.max())
foo['first'] = foo.sess_id.map(foo.groupby('sess_id').DATE.min())
但我认为没有必要,您可以直接使用 groupby 数据框。
解决您的问题的一种方法是在 sess_id
列中查找缺失值,并将自定义函数应用于相应的日期:
def my_custom_function(time):
current_sessions = my_agg.loc[(my_agg['min']<time) & (my_agg['max']>time)]
count = len(current_sessions)
if count == 0:
return 0
if count > 1:
return -99
return current_sessions.index[0]
my_agg = foo.groupby('sess_id').DATE.agg([min,max])
foo.loc[foo.sess_id.isnull(),'sess_id'] = foo.loc[foo.sess_id.isnull(),'DATE'].apply(my_custom_function)
输出:
DATE sess_id
0 2018-01-01 00:19:01 a
1 2018-01-01 00:19:05 b
2 2018-01-01 00:21:07 a
3 2018-01-01 00:22:07 b
4 2018-01-01 00:25:09 c
5 2018-01-01 00:25:11 -99
6 2018-01-01 00:27:28 c
7 2018-01-01 00:29:29 a
8 2018-01-01 00:30:35 b
9 2018-01-01 00:31:16 b
10 2018-01-01 00:35:22 0
我认为它执行了您正在寻找的内容,尽管您在问题中发布的输出似乎包含拼写错误。