Использование Numpy для фильтрации двух кадров данных

#python #pandas #numpy

Вопрос:

У меня есть два фрейма данных. Они структурированы следующим образом:

df a

Письмо ID
A 3
B 4

df b

Письмо ID Ценность
A 3 100
B 4 300
B 4 100
B 4 150
A 3 200
A 3 400

Мне нужно взять для каждой комбинации букв и идентификатора в df A значения из df B и запустить функцию выброса.

В настоящее время я использую более 40 000 строк A и список из 4 500 000 строк списка b

 a['Results'] =  a.apply(lambda x: outliers(b[(b['Letter']==x['Letter']) amp; (b['ID']==x['ID'])]['value'].to_list()),axis=1)
 

Как вы можете себе представить, это длится целую вечность. Есть ли какая-то ошибка, которую я совершаю, или что-то, что может улучшить этот код?

Ответ №1:

Я бы сначала объединил каждую комбинацию [Letter, ID] in df_b в список , используя .groupby , затем объединил с df_a вашей outliers функцией и применил ее впоследствии. Должно быть быстрее:

 df_a["results"] = df_a.merge(
    df_b.groupby(["Letter", "ID"])["Value"].agg(list),
    left_on=["Letter", "ID"],
    right_index=True,
    how="left",
)["Value"].apply(outliers)
print(df_a)
 

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

1. Большое спасибо. Я думаю, это просто облегчает задачу, так как вы не просеиваете 4,5-метровые ряды, верно?

2. @ShivR Точно, переход на 40_000x вниз по 4_500_000 строкам занимает много времени.

Ответ №2:

Сначала вы можете попытаться объединить наборы данных a и b, а затем запустить группу по буквам и идентификаторам, агрегировать значение по функции выбросов.

 pd.merge(a,b,how="inner",on = ['letter','ID']).groupby(['letter','ID']).agg(outlier).reset_index()