DataFrame teilt Zeilen unter mehreren Bedingungen in zwei Sätze auf, unerwartetes VerhaltenPython

Python-Programme
Anonymous
 DataFrame teilt Zeilen unter mehreren Bedingungen in zwei Sätze auf, unerwartetes Verhalten

Post by Anonymous »

Ich versuche, meine Daten basierend auf den Eigenschaften und der Größe der Daten in zwei Sätze (setA und setB) aufzuteilen.
Angenommen, ein Datenrahmen mit Zufallsdaten:

Code: Select all

import pandas as pd
import string
import random

# Create a DataFrame with random data
names = [''.join(random.choices(string.ascii_uppercase + string.digits, k=5)) for i in range(100)]
prop1 = [random.randint(0, 100) for i in range(100)]
prop2 = [random.randint(0, 100) for i in range(100)]
prop3 = [random.randint(0, 100) for i in range(100)]

df = pd.DataFrame({'name': names, 'prop1': prop1, 'prop2': prop2, 'prop3': prop3})
Ich möchte Namen zu SetA hinzufügen, sodass keine Eigenschaft in SetB in SetA vorhanden ist.
Dies ist mein aktueller Code. Ich würde erwarten, dass die Überlappung zwischen SetA und SetB am Ende 0 beträgt. Aber wie Sie sehen können, bleibt die Überlappung bestehen, wenn Sie diesen Code ausführen. Ich verstehe nicht, was hier falsch läuft. Soweit ich weiß, i:
  • Besorgen Sie sich einen zufälligen Satz von Eigenschaften.
  • Wählen Sie alle Datenpunkte mit diesen Eigenschaften aus.
  • Fügen Sie die Datenpunkte zu SetA hinzu.
  • Entfernen Sie ausgewählte Datenpunkte aus dem ursprünglichen Satz.
  • Nach Erreichen eines Schwellenwerts setzen Sie die verbleibenden Daten auf SetB.
  • SetB sollte keine Eigenschaften enthalten (z entweder prop1 und/oder prop2 und/oder prop3) von setA.
Sehr dankbar, wenn jemand darauf hinweisen kann, wo ich den Fehler mache.

Code: Select all

# Initialize sets A and B
setA = pd.DataFrame(columns=df.columns)
setB = pd.DataFrame(columns=df.columns)

# Calculate the target size for setA (approximately 70% of the dataset)
target_size = len(df) * 0.7

while len(setA) < target_size and len(df) > 0:
print(f'len at start of loop {len(df)}')
# Take the first row from the shuffled DataFrame
row = df.iloc[0]

# Get values for prop1, prop2, prop3
prop1, prop2, prop3 = row['prop1'], row['prop2'], row['prop3']

# Filter DataFrame to find rows with the same values for prop1-3
sim_1 = df[df['prop1'] == prop1]
sim_2 = df[df['prop2'] == prop2]
sim_3 = df[df['prop3'] == prop3]

# similar_rows = df[(df['prop1'] == prop1) | (df['prop2'] == prop2) | (df['prop3'] == prop3)]

# Remove rows from the original DataFrame
indices = list(set(sim_1.index.tolist() + sim_2.index.tolist() + sim_3.index.tolist()))
df = df.drop(index=indices)
df = df.reset_index(drop=True)

#assert nothing is left
assert len(df[df["prop1"] == prop1]) == 0
assert len(df[df["prop2"] == prop2]) == 0
assert len(df[df["prop3"] == prop3]) == 0

# Add the similar rows to setA
# setA = pd.concat([setA, similar_rows])
setA = pd.concat([setA, sim_1])
setA = pd.concat([setA, sim_2])
setA = pd.concat([setA, sim_3])

# Any remaining rows in df will go to setB
setB = df

assert setB[setB['prop1'].isin(setA['prop1'])].empty == True
BEARBEITEN
Ein konkretes Beispiel dafür, was ich zu tun versuche.
Wenn es sich bei den Daten um eine Sammlung von Personen und deren Ernährung für eine bestimmte Kategorie handelt:

Code: Select all

import pandas as pd

veggies = ['paprika', 'potato', 'potato', 'paprika', 'yam', 'zuchinni', 'zuchinni', 'yam', 'potato', 'potato']
fruits = ['apple', 'apple', 'apple', 'apple', 'banana', 'banana', 'banana', 'banana', 'cococonut', 'cococonut']
meats = ['chicken', 'cow', 'cow', 'chicken', 'sheep', 'sheep', 'fish', 'fish', 'cow', 'chicken']
names = ['person1', 'person2', 'person3', 'person4', 'person5', 'person6', 'person7', 'person8','person9','person10']

df = pd.DataFrame({'name': names, 'veggies': veggies, 'fruits': fruits, 'meats': meats})
In meinem ersten Durchlauf überprüfe ich, ob eines der ersten Produkte vorhanden ist, in diesem Fall das Gemüsepaprika, der Fruchtapfel und das Fleischhähnchen.

Code: Select all

df[(df['veggies'] == 'paprika') | (df['fruits'] == 'apple') | (df['meats'] == 'chicken')]
Dann wäre das Ergebnis:

Code: Select all

index name      veggies fruits    meats
0     person1   paprika apple     chicken
1     person2   potato  apple     cow
2     person3   potato  apple     cow
3     person4   paprika apple     chicken
9     person10  potato  cococonut chicken
Da wir dann auch Kartoffel und Kokosnuss und Kuh als neue Kategorien finden, prüfen wir diese.

Code: Select all

df[(df['veggies'] == 'potato') | (df['fruits'] == 'cococonut') | (df['meats'] == 'cow')]
Dies gibt die folgenden Daten zurück

Code: Select all

index name      veggies fruits      meats
1     person2   potato  apple       cow
2     person3   potato  apple       cow
8     person9   potato  cococonut   cow
9     person10  potato  cococonut   chicken
Wir addieren diese zusammen, um insgesamt Folgendes zu finden: (dies würde setA werden)

Code: Select all

index name      veggies fruits    meats
0     person1   paprika apple     chicken
1     person2   potato  apple     cow
2     person3   potato  apple     cow
3     person4   paprika apple     chicken
8     person9   potato  cococonut   cow
9     person10  potato  cococonut chicken
Dann prüfen wir, ob wir einen bestimmten Schwellenwert erreichen. Lass uns auf 50 % prüfen. Da wir 6/10 Datenpunkte haben, liegen wir über 50 % und behalten person1,2,3,4,9,10 als setA. Der Rest der Daten wird in setB (person5, 6, 7, 8) abgelegt.
setB wäre:

Code: Select all

index name      veggies     fruits  meats
4     person5   yam         banana  sheep
5     person6   zuchinni    banana  sheep
6     person7   zuchinni    banana  fish
7     person8   yam         banana  fish
Angenommen, wir überprüfen den Schwellenwert bei 70 % und stellen fest, dass wir ihn noch nicht erreicht haben. Also suchen wir nach der ersten neuen Probe: Person5 mit Yamswurzel, Banane, Schaf. Da wir dann auch Zuchinni und Fisch finden, besteht die erste mögliche Lösung über 70 % darin, dass jede Person in einem Set SetA vollständig ausfüllt, während SetB leer wäre.
Es macht mir nichts aus, welche Gruppierung in SetA oder SetB gelangt, nur dass wir alle Muster zwischen SetA und SetB auf ungefähr ein bestimmtes Verhältnis entwirren können. In Wirklichkeit hat jede Kategorie Tausende von Klassen und ich finde eine Teilmenge, bei der es keine Überschneidung zwischen den Klassen in einer der Kategorien gibt.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post