Оптимизируйте Groupby.apply () с помощью пользовательских функций или альтернатив векторной функции. - PullRequest
0 голосов
/ 04 июля 2019

Я пытаюсь оптимизировать или избежать pandas Метод Groupby.apply (), который берет мою пользовательскую функцию и применяет ее для каждого идентификатора

Версия Pandas: 0.23.4

Исходный кадр данных

ID    Val1   Val2  Val3
1111  2      2      3
1111  NAN    9     10
1111  NAN    7      4
2222  NAN    2      3
2222  3      2      3
3333  6    NAN      5
3333  NAN    2      3

Я группирую на уровне идентификатора и вызываю функцию применения, которая управляет пользовательской функцией

df_dedup = df.groupby('ID').apply(lambda x : my_func(data = x))

Моя функция my_func удаляет дубликаты на уровне идентификатора, выбирая ту, которая имеет наибольшие пропущенные значения.
Если количество не пропущенных значений одинаково (например, ID 3333), тогда я выбираю случайным образом одно.

ID    Val1   Val2  Val3
1111  2      2      3  (This will be picked, highest non-missing ID)
1111  NAN    9     10
1111  NAN    7      4

2222  NAN    2      3
2222  3      2      3 (This will be picked, highest non-missing ID)

3333  6    NAN      5
3333  NAN    2      3 (Random Pick)

apply () удобно объединяет все 3 идентификатора, и результирующий кадр данных равен

Final De-duped Dataframe 

ID    Val1   Val2  Val3
1111  2      2     3
2222  3      2     3
3333  NAN    2     3

Теперь, как мне это сделать без использования groupby.apply () или apply ()?Есть ли альтернатива?

Он работает вечно 1 миллион записей запущен за ~ 20 минут

1 Ответ

1 голос
/ 04 июля 2019

В данном случае, разделите фрейм данных на два, исходя из вашего состояния, у одного есть nan для всех рядов, или для некоторой строки, не содержащей nan, тогда мы будем рассматривать их по-разному.

s1=df.isnull().any(1).groupby(df['ID']).transform('all')
df1=df[s1];df2=df[~s1]
df1=df1.sort_values(['Val3']).drop_duplicates('ID',keep='last')
df2=df2.groupby('ID').apply(pd.DataFrame.sample,n=1).reset_index(level=0,drop=True)
df=pd.concat([df1,df2]).sort_index()
df
Out[178]: 
     ID Val1 Val2  Val3
0  1111    2    2     3
4  2222    3    2     3
5  3333    6  NaN     5
...