Le code ci-dessous vise à retourner un df
qui compte le nombre de points positifs et négatifs à partir d'un point de référence (mainX, mainY)
. Celle-ci est déterminée par le Direction
. Ceux-ci sont séparés en deux groupes (I, J)
. Les points sont situés dans X,Y
chacun ayant une valeur relative Label
.
J'ai donc réparti les points dans leurs groupes respectifs. Je sous-divise ensuite les df
en df positifs/négatifs en utilisant une requête. Ces df sont ensuite regroupés par temps et comptés dans une colonne séparée. Ces df's sont ensuite concaténés.
Tout cela semble très inefficace. Surtout si j'ai de nombreuses valeurs uniques dans Group
. Par exemple, je dois répliquer la séquence d'interrogation à la suite pour renvoyer les comptes de Group J
.
Existe-t-il un moyen plus efficace d'obtenir le résultat escompté ?
import pandas as pd
df = pd.DataFrame({
'Time' : ['09:00:00.1','09:00:00.1','09:00:00.1','09:00:00.1','09:00:00.1','09:00:00.1','09:00:00.2','09:00:00.2','09:00:00.2','09:00:00.2','09:00:00.2','09:00:00.2'],
'Group' : ['I','J','I','J','I','J','I','J','I','J','I','J'],
'Label' : ['A','B','C','D','E','F','A','B','C','D','E','F'],
'X' : [8,4,3,8,7,4,2,3,3,4,6,1],
'Y' : [3,6,4,8,5,2,8,8,2,4,5,1],
'mainX' : [5,5,5,5,5,5,5,5,5,5,5,5],
'mainY' : [5,5,5,5,5,5,5,5,5,5,5,5],
'Direction' : ['Left','Right','Left','Right','Left','Right','Left','Right','Left','Right','Left','Right']
})
# Determine amount of unique groups
Groups = df['Group'].unique().tolist()
# Subset groups into separate df's
Group_I = df.loc[df['Group'] == Groups[0]]
Group_J = df.loc[df['Group'] == Groups[1]]
# Separate into positive and negative direction for each group
GroupI_Pos = Group_I.query("(Direction == 'Right' and X > mainX) or (Direction == 'Left' and X < mainX)").copy()
GroupI_Neg = Group_I.query("(Direction == 'Right' and X < mainX) or (Direction == 'Left' and X > mainX)").copy()
# Count of items per timestamp for Group I
GroupI_Pos['GroupI_Positive_Count'] = GroupI_Pos.groupby(['Time'])['Time'].transform('count')
GroupI_Neg['GroupI_Negative_Count'] = GroupI_Neg.groupby(['Time'])['Time'].transform('count')
# Combine Positive/Negative dfs
df_I = pd.concat([GroupI_Pos, GroupI_Neg], sort = False).sort_values(by = 'Time')
# Forward fill Nan grouped by time
df_I = df_I.groupby(['Time']).ffill()
Sortie prévue :
Time Group Label X Y mainX mainY Direction GroupI_Positive_Count GroupI_Negative_Count GroupJ_Positive_Count GroupJ_Negative_Count
0 09:00:00.1 I A 8 3 5 5 Left 1 2 1 2
1 09:00:00.1 J B 4 6 5 5 Right 1 2 1 2
2 09:00:00.1 I C 3 4 5 5 Left 1 2 1 2
3 09:00:00.1 J D 8 8 5 5 Right 1 2 1 2
4 09:00:00.1 I E 7 5 5 5 Left 1 2 1 2
5 09:00:00.1 J F 4 2 5 5 Right 1 2 1 2
6 09:00:00.2 I A 2 8 5 5 Left 2 1 0 3
7 09:00:00.2 J B 3 8 5 5 Right 2 1 0 3
8 09:00:00.2 I C 3 2 5 5 Left 2 1 0 3
9 09:00:00.2 J D 4 4 5 5 Right 2 1 0 3
10 09:00:00.2 I E 6 5 5 5 Left 2 1 0 3
11 09:00:00.2 J F 1 1 5 5 Right 2 1 0 3