Jobs an Teilnehmer zuweisen - pandas dataframe
Verfasst: Montag 6. Januar 2020, 16:40
Hallo
Ich habe ein langes dataframe (ca. 400 Zeilen) mit folgenden Spalten:
Bedingung 1:
Die Anzahl der Leute in der Liste ist immer ein Vielfaches von 9 (z.B. 27 oder 288). Das ursprüngliche dataframe (df) soll am Ende in kleinere Dataframes (clusters) zerteilt werden mit der Größe von 9 Teilnehmern pro Cluster.
Kurzes Beispiel:
Aus einem ursprünglichen df mit 27 Teilnehmern werden 3 dataframes (cluster) mit jeweils 9 Teilnehmer. In jedem dieser drei Cluster befinden sich dann jeweils 3 Leute für die Vorspeise, 3 Leute für das Hauptgericht und 3 Leute für die Nachspeise.
Bedingung 2:
Da die Personen zur Ausführung des Jobs eine Küche brauchen, dürfen Personen im selben Haushalt (identische Koordinaten: Latitude, Longitude und Floor) nicht den selben Job zugewiesen bekommen! Andernfalls würden sie sich in der Küche nur behindern. Macht ja auch Sinn, denn es können nicht 2 Personen gleichzeitig in der selben Küche ein Hauptgericht kochen. Jedoch sollten Personen in einem Cluster auch nicht zuweit von einander entfernt sein, weshalb ich in meinem Ansatz (siehe unten), die Personen erstmal nach den Koordinaten ordne.
Meine Frage:
Wie teile ich die Jobs automatisiert zu?
Mein Ansatz:
Leider funktioniert dieser Ansatz noch nicht richtig. Im Beispiel ist das df lediglich 9 Teilnehmer lang. Da alle an unterschiedlichen Orten wohnen (Latitude, Longitude, floor), sollte jeder einen Job zugewiesen bekommen. Was machen ich falsch?
Vielleicht habt ihr einige Ideen. Der Code kann direkt in Google Colab ausgeführt werden. Dort könnt ihr auch gerne Verbesserungen einführen: https://colab.research.google.com/drive ... RzXlpJkvOh
Ich habe ein langes dataframe (ca. 400 Zeilen) mit folgenden Spalten:
- ID
- latitude
- longitude
- floor
Bedingung 1:
Die Anzahl der Leute in der Liste ist immer ein Vielfaches von 9 (z.B. 27 oder 288). Das ursprüngliche dataframe (df) soll am Ende in kleinere Dataframes (clusters) zerteilt werden mit der Größe von 9 Teilnehmern pro Cluster.
Kurzes Beispiel:
Aus einem ursprünglichen df mit 27 Teilnehmern werden 3 dataframes (cluster) mit jeweils 9 Teilnehmer. In jedem dieser drei Cluster befinden sich dann jeweils 3 Leute für die Vorspeise, 3 Leute für das Hauptgericht und 3 Leute für die Nachspeise.
Bedingung 2:
Da die Personen zur Ausführung des Jobs eine Küche brauchen, dürfen Personen im selben Haushalt (identische Koordinaten: Latitude, Longitude und Floor) nicht den selben Job zugewiesen bekommen! Andernfalls würden sie sich in der Küche nur behindern. Macht ja auch Sinn, denn es können nicht 2 Personen gleichzeitig in der selben Küche ein Hauptgericht kochen. Jedoch sollten Personen in einem Cluster auch nicht zuweit von einander entfernt sein, weshalb ich in meinem Ansatz (siehe unten), die Personen erstmal nach den Koordinaten ordne.
Meine Frage:
Wie teile ich die Jobs automatisiert zu?
Mein Ansatz:
Code: Alles auswählen
import pandas as pd
from math import radians, sin, cos, atan2, sqrt
# function that calculates the shortes distance between two points given by the latitude and longitude
def distance(lat1, lon1, lat2, lon2):
R = 6373.0 # approximate radius of earth in km
lat1 = radians(lat1)
lon1 = radians(lon1)
lat2 = radians(lat2)
lon2 = radians(lon2)
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
distance = (R * c)
return distance # in unit 'kilometers'
# dataframe of all people. Size is always multiple of 9.
d = {
'latitude': [1.1,1.2,1.1, 1.3,1.3,1.4,1.4,1.4,1.4],
'longitude': [1.1, 2, 1.1, 1.3, 1.3, 1.8, 1.8, 1.8, 1.8],
'floor': [3,1,2,2,4,3,2,1,4],
'id': [1,2,3,4,5,6,7,8,9]
}
df = pd.DataFrame(data=d)
df.set_index('id', drop=False, inplace=True)
df['host'] = 'None'
df['group'] = 'None'
max_distance = 85
# Sort people for distance
emptyGroupList = df.loc[df['host'] == 'None'].sort_values(['latitude', 'longitude', 'floor'], ascending=True)
print(emptyGroupList)
group = []
groupNumber = 0
for index, person in df.iterrows():
if len(group) == 3:
for group_person in group:
df.at[group_person['id'], 'group'] = groupNumber
groupNumber += 1
group = []
if len(group) == 0:
group.append(person)
else:
for group_person in group:
#print(group_person['floor'])
dist = distance(person['latitude'], person['longitude'], group_person['latitude'], group_person['longitude'])
if 0 < dist <= max_distance:
group.append(person)
print(df)
Vielleicht habt ihr einige Ideen. Der Code kann direkt in Google Colab ausgeführt werden. Dort könnt ihr auch gerne Verbesserungen einführen: https://colab.research.google.com/drive ... RzXlpJkvOh