python - 如何根据条件从不同的列中创建一个组?
问题描述
我有一个看起来像这样的数据框:
Air-line City Time ID
0 easyJet London 20:40 1
1 airberlin Berlin 10:30 2
2 Emarite Dubai 21:45 3
3 Qatar Airways Newyork 10:30 4
4 easyJet London 20:46 5
5 airberlin Berlin 10:34 6
.
.
.
.
99 Qatar Airways London 20:40 13
100 airberlin Berlin 10:32 20
我想要做的是使用 groupby 并根据列 ID 从列“Air-lines”、“City”和“Time”中创建一个组,以更改列 ID 中的值。因此,Air-line、City 和 Time 中具有相同值的行应该具有相同的 ID。为此,我有以下代码:
df['ID'] = df.groupby(['Air-line','City','Time'])['ID'].transform('first')
但问题是我想更改代码,以便不仅包括“时间”列中的确切值,还应该包括 +6 或 -6 分钟之间的差值。
我期望的是:
Air-line City Time ID
0 easyJet London 20:40 1
1 airberlin Berlin 10:30 2
2 Emarite Dubai 21:45 3
3 Qatar Airways Newyork 10:30 4
4 easyJet London 20:46 1
5 airberlin Berlin 10:34 2
.
.
.
.
99 Qatar Airways London 20:40 13
100 airberlin Berlin 10:32 2
你能告诉我如何添加这个条件吗?任何帮助将不胜感激。非常感谢
解决方案
您可以time
使用 6 分钟的步骤对列进行分类,如下所示。我在这里使用pandas.cut
功能。当bins
我传递从pd.date_range
. 在pd.cut
我使用right=False
包含区间左侧的点并排除区间右侧的点。
我以一个小的数据框为例,但你会明白的。
import datetime
import pandas as pd
df = pd.DataFrame({
'time': ['20:30', '20:33', '20:36', '20:40', '20:42'],
'ID': [1, 2, 3, 4, 5],
})
df['time'] = pd.to_datetime(df['time'])
start = df['time'].min()
end = df['time'].max() + pd.Timedelta('6min')
bins = pd.date_range(start, end, freq='6T')
cut = pd.cut(df['time'], bins=bins, right=False)
df['time_category'] = cut
df['ID'] = df.groupby('time_category')['ID'].transform('first')
print(df)
输出
time ID time_category
0 2021-02-03 20:30:00 1 [2021-02-03 20:30:00, 2021-02-03 20:36:00)
1 2021-02-03 20:33:00 1 [2021-02-03 20:30:00, 2021-02-03 20:36:00)
2 2021-02-03 20:36:00 3 [2021-02-03 20:36:00, 2021-02-03 20:42:00)
3 2021-02-03 20:40:00 3 [2021-02-03 20:36:00, 2021-02-03 20:42:00)
4 2021-02-03 20:42:00 5 [2021-02-03 20:42:00, 2021-02-03 20:48:00)
无日期分箱
还有另一种方法。您提到您需要避免在分组中使用日期。不幸的是,我没有设法使用 pandas internals 扩展解决方案。但这可以通过另一种方式实现。
让我们bins
从 00:00 到 23:54 手动创建并为每个人分配密钥。然后我们将使用一个categorize
函数将相应的键分配给时间值。请注意,我在这里创建new_time
了使用time.strptime
转换的列。就是这个专栏,然后我对其进行分类。
import itertools
from functools import partial
import time
import pandas as pd
bins = [
time.strptime(f'{hour}:{minute}', '%H:%M')
for hour, minute in itertools.product(range(24), range(0, 60, 6))
]
bins_mapping = {
index: value
for index, value in enumerate(sorted(bins))
}
def categorize(t, bins_mapping):
for index, value in bins_mapping.items():
if value > t:
break
return index
df = pd.DataFrame({
'time': ['20:30', '20:33', '20:36', '20:40', '20:42'],
'ID': [1, 2, 3, 4, 5],
})
df['new_time'] = df['time'].apply(lambda x: time.strptime(x, '%H:%M'))
df['time_category'] = df['new_time'].apply(
partial(categorize, bins_mapping=bins_mapping)
)
df['ID'] = df.groupby('time_category')['ID'].transform('first')
print(df)
输出
time ID new_time time_category
0 20:30 1 (1900, 1, 1, 20, 30, 0, 0, 1, -1) 206
1 20:33 1 (1900, 1, 1, 20, 33, 0, 0, 1, -1) 206
2 20:36 3 (1900, 1, 1, 20, 36, 0, 0, 1, -1) 207
3 20:40 3 (1900, 1, 1, 20, 40, 0, 0, 1, -1) 207
4 20:42 5 (1900, 1, 1, 20, 42, 0, 0, 1, -1) 208
推荐阅读
- java - 我应该为无效输入抛出已检查或未检查的异常吗?
- spring - html页面中的引导模式
- c++ - 如何在 QSqlTableModel 和 Q_OBJECT 之间不发生冲突的情况下构建我的类?
- python - 梯度计算所需的变量之一已被就地操作修改
- c++ - 在 C++ 中使用 shared_ptr 时,use_count 变为 -1
- unity3d - 将动画添加到输入字段并保存转换
- javascript - Javascript 确认使用来自远程服务器的 HTML 使 Safari 冻结
- angular - 离子 ionChange 给出 ExpressionChangedAfterItHasBeenCheckedError
- python - FlaskSQLAlchemy 查询很慢
- android - 将“app:”属性添加到Android中的自定义样式