DataFrame разделяет строки по нескольким условиям на два набора, неожиданное поведениеPython

Программы на Python
Ответить
Anonymous
 DataFrame разделяет строки по нескольким условиям на два набора, неожиданное поведение

Сообщение Anonymous »

Я пытаюсь разделить свои данные на два набора (setA и setB) на основе свойств и размера данных.
Для кадра данных случайных данных:

Код: Выделить всё

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})
Я хочу добавить имена в setA так, чтобы какое-либо свойство из setB не присутствовало в setA.
Это мой текущий код, я ожидаю, что в конце перекрытие между setA и setB будет равно 0. Но, как вы можете видеть, когда вы запускаете этот код, перекрытие остается. Я не понимаю, что здесь происходит не так. Насколько я понимаю, я:
  • Получить случайный набор свойств.
  • Выбрать все точки данных с этими свойствами.
  • Добавить точки данных в setA.
  • Удалить выбранные точки данных из исходного набора.
  • После достижения порогового значения установить оставшиеся данные в setB.
  • SetB не должен содержать no свойства (для prop1, и/или prop2, и/или prop3) setA.
Буду признателен, если кто-нибудь укажет, где я делаю ошибку.

Код: Выделить всё

# 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
РЕДАКТИРОВАТЬ
Конкретный пример того, что я пытаюсь сделать.
Если данные представляют собой набор людей и того, что они едят, для определенной категории:

Код: Выделить всё

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})
В моей первой итерации я проверяю наличие любого из первых элементов, в данном случае овощной паприки, фруктового яблока и мяса курицы.

Код: Выделить всё

df[(df['veggies'] == 'paprika') | (df['fruits'] == 'apple') | (df['meats'] == 'chicken')]
Тогда результат будет такой:

Код: Выделить всё

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
Поскольку мы также находим картофель, кокос и корову как новые категории, мы проверяем их.

Код: Выделить всё

df[(df['veggies'] == 'potato') | (df['fruits'] == 'cococonut') | (df['meats'] == 'cow')]
Это возвращает следующие данные

Код: Выделить всё

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
Мы складываем их вместе, чтобы найти итог: (это станет setA)

Код: Выделить всё

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
Затем мы проверяем, достигли ли мы определенного порога. Давайте проверим на 50%. Поскольку у нас есть 6/10 точек данных, мы превышаем 50% и оставляем person1,2,3,4,9,10 как setA. Остальные данные помещаются в setB (person5, 6, 7, 8).
setB будет:

Код: Выделить всё

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
Теперь допустим, мы проверяем порог на уровне 70 % и обнаруживаем, что еще не достигли его. Итак, ищем первый новый образец: person5 с бататом, бананом, овцой. Поскольку тогда мы также находим цукини и рыбу, первое возможное решение выше 70% состоит в том, что каждый человек в одном наборе, как мы ожидаем, полностью заполнит набор A, в то время как набор B будет пуст.
Я не возражаю, какая группа попадает в набор A или набор B, просто мы можем распутать все закономерности между набором A и набором B примерно до определенного соотношения. На самом деле в каждой категории есть тысячи классов, и я нахожу подмножество, в котором нет совпадений между классами ни в одной из категорий.

Подробнее здесь: https://stackoverflow.com/questions/772 ... ur-unexpec
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»