Векторизация сложных операций над фреймами данных в Python

#python #pandas #numpy

#python #pandas #numpy

Вопрос:

Я новичок в Python и использую Pandas и NumPy. У меня есть фрейм данных df , и я хочу найти значения столбца, OZNAKA_PARTIJE для которых значение KLIJENT_ID не является уникальным, и удалить такие строки.

Я стараюсь максимально избегать циклов, но условие здесь кажется слишком сложным, чтобы использовать методы, которые я знаю. Есть ли какой-либо возможный способ написать векторизованную версию этого кода, используя некоторые функции из Pandas или NumPy?

Выполнение этого цикла занимает много времени и заканчивается ошибкой памяти.

 party_labels = df['OZNAKA_PARTIJE'].unique().tolist()

for i in party_labels:
    extracted_party_label = df.loc[df['OZNAKA_PARTIJE'] == i]

    # check if you can use the drop method below
    if (extracted_party_label[ extracted_party_label['OZNAKA_PARTIJE'] == i ].index.is_unique == False):
        print('Drop method might not work properly')

    # if there exists multiple client ids for given party label
    if (extracted_party_label['KLIJENT_ID'].is_unique == False):
        # delete rows with that party label in the original dataset
        df.drop(df[ df['OZNAKA_PARTIJE'] == i ].index , inplace=True)
  

ОБНОВЛЕНИЕ: ответили!

Основываясь на ответе, опубликованном @Chris, я придумал это.

 df2 = df.copy()
gb = df2.groupby('OZNAKA_PARTIJE')['KLIJENT_ID'].nunique()
party_labels = df2['OZNAKA_PARTIJE'].unique().tolist()
mask = gb[df2['OZNAKA_PARTIJE']] == 1
df2 = df2[ mask.values ]
  

Комментарии:

1. можете ли вы предоставить некоторые примеры данных?

Ответ №1:

Если у вас есть третий столбец с любым значением, вы можете сгруппировать по первому, второму и посчитать третий. Количество будет равно 1, если первые два уникальны. Количество будет больше, если есть дубликаты. Вы можете использовать это для создания логических масок, а затем фильтровать df по ним.

 import pandas as pd

df = pd.DataFrame([[1,2,'a'],[1,2,'b'],[2,3,'c'],[3,4,'d'],[3,8,'e']], columns=['OZNAKA_PARTIJE', 'KLIJENT_ID', 'OTHER'])

df = df.groupby(['OZNAKA_PARTIJE','KLIJENT_ID'])['OTHER'].count() == 1
df = df.reset_index()
df[df['OTHER']==True]


OZNAKA_PARTIJE  KLIJENT_ID  OTHER
2               3           True
3               4           True
3               8           True
  

Комментарии:

1. Вам никогда не нужно будет делать == True , используя df[df['OTHER']] то же самое

2. @Chris, хотя ваш ответ — это не то, что я ищу, основываясь на нем, я придумал альтернативный способ группировки, но я все еще работаю над фильтрацией фрейма данных.