У меня более сложная проблема с пандами.
Я объединяю два кадра данных в столбце V
, который определяет группы.
Оба кадра данных также имеют уникальный столбец ID
и Time
столбец.
После объединения я вычисляю Timedelta
между этими двумя столбцами и отфильтровываю отрицательные значения:
import pandas as pd
L11 = ['V1','V1','V1','V2','V2','V3','V3','V3','V3']
L12 = [1,2,3,4,5,6,7,8,9]
L13 = [pd.Timestamp("1.1.1980 12:12:12"),
pd.Timestamp("1.1.1980 13:12:12"),
pd.Timestamp("1.2.1980 01:12:12"),
pd.Timestamp("1.1.1980 14:12:12"),
pd.Timestamp("1.1.1980 16:12:12"),
pd.Timestamp("1.1.1980 16:12:12"),
pd.Timestamp("1.1.1980 14:12:12"),
pd.Timestamp("1.1.1980 13:12:12"),
pd.Timestamp("1.2.1980 10:12:12")]
L21 = ['V1','V1','V2','V3','V3','V3','V3','V3','V3']
L22 = [11,12,13,14,15,16,17,18,19]
L23 = [pd.Timestamp("1.1.1980 12:12:12"),
pd.Timestamp("1.1.1980 13:12:12"),
pd.Timestamp("1.1.1980 14:12:12"),
pd.Timestamp("1.1.1980 14:12:12"),
pd.Timestamp("1.1.1980 16:12:12"),
pd.Timestamp("1.1.1980 18:12:12"),
pd.Timestamp("1.1.1980 11:12:12"),
pd.Timestamp("1.1.1980 12:12:12"),
pd.Timestamp("1.2.1980 10:12:12")]
df1 = pd.DataFrame({'V':L11,'ID1':L12,'Time1':L13})
df2 = pd.DataFrame({'V':L21,'ID2':L22,'Time2':L23})
df = pd.merge(df1,df2,on='V')
df["Delta"] = df.Time1-df.Time2
df = df[df.Delta>pd.Timedelta(0)].copy()
df = df.drop(["Time1","Time2"],axis=1)
Дополнительно я подсчитываю, сколько записей на V
-группы присутствуют в каждом фрейме данных и получают меньшее значение, которое я называю Max
, потому что это будет максимально допустимое значение объединенных записей на группу.Это гарантирует, что с обеих сторон ID
-значения для V
-группы могут быть уникальными.
df1g = df1.groupby("V").ID1.count().reset_index().rename(columns={"ID1":"C1"})
df2g = df2.groupby("V").ID2.count().reset_index().rename(columns={"ID2":"C2"})
df12g = pd.merge(df1g,df2g,on='V')
df12g["Max"] = df12g[["C1","C2"]].min(axis=1)
df = pd.merge(df,df12g[['V','Max']],on='V')
df = df.sort_values(['V','Delta']).reset_index(drop=True)
Это мой отсортированный пример данных:
V ID1 ID2 Delta Max
0 V1 2 11 01:00:00 2
1 V1 3 12 12:00:00 2
2 V1 3 11 13:00:00 2
3 V2 5 13 02:00:00 1
4 V3 8 18 01:00:00 4
5 V3 6 14 02:00:00 4
6 V3 7 18 02:00:00 4
7 V3 8 17 02:00:00 4
8 V3 7 17 03:00:00 4
9 V3 6 18 04:00:00 4
10 V3 6 17 05:00:00 4
11 V3 9 16 16:00:00 4
12 V3 9 15 18:00:00 4
13 V3 9 14 20:00:00 4
14 V3 9 18 22:00:00 4
15 V3 9 17 23:00:00 4
- Группа
V1
имеет 3 записи, но разрешена только 2 - Группа
V2
имеет 1 запись и разрешена только 1 - Группа
V3
имеет 12 записей, но разрешена только 4
Теперь мне нужно найти для каждой ID1
запись ID2
с самым низким Delta
, но комбинации должны быть уникальными.
Это означает, что в строке 4
ID1 8
в паре с ID2 18
в строке 6
ID1 7
не должно быть в паре с ID2 18
.
По сути, я хочу получить такой результат:
V ID1 ID2 Delta Max
0 V1 2 11 01:00:00 2
1 V1 3 12 12:00:00 2
3 V2 5 13 02:00:00 1
4 V3 8 18 01:00:00 4
5 V3 6 14 02:00:00 4
8 V3 7 17 03:00:00 4
11 V3 9 16 16:00:00 4
И яя не могу понять, как этого добиться.
Простые подходы, такие как
df1 = df.drop_duplicates('ID1')
df2 = df.drop_duplicates('ID2')
result = pd.merge(df1,df2)
, очевидно, не работают должным образом.
Возможно ли даже решитьэто без перебора отсортированных строк и построения памяти из уже занятых ID2
-значений?