Как получить доступ к данным наиболее эффективно в pandas - PullRequest
3 голосов
/ 04 апреля 2020

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

ВЫПОЛНЕНО

Использование группировки по

female_admitted_rate = df.groupby('gender').get_group('female')[df['admitted'] == True].count()/len(df.groupby('gender').get_group('female'))```

```python
[OUT]
student_id    0.287938
gender        0.287938
major         0.287938
admitted      0.287938
dtype: float64

Использование простого pandas

len(df[(df['gender']=='female') & (df['admitted'])])/(len(df[df['gender']=='female']))

[Out] 0.28793774319066145

Использование запроса

len(df.query("gender == 'female' & admitted"))/len(df.query("gender == 'female'"))

[Out] 0.28793774319066145

ВОПРОСЫ

  • Что бы вы использовали, чтобы получить эту информацию?
  • Есть ли особое преимущество для одного из показанных подходов?
  • Есть ли какой-то подход, который абсолютно не имеет смысла для вас, ребята?
  • Есть ли выигрыш в производительности червячного вычисления при использовании одного из трех выше других, когда он приходит к большим наборам данных?

1 Ответ

2 голосов
/ 04 апреля 2020

Я думаю, вам нужно только DataFrame.loc[] + Series.mean():

df.loc[df['gender'].eq('female'), 'admitted'].mean()

True интерпретируется как 1 и False как 0 от Series.mean

Вы можете проверить с помощью timeit

%%timeit
df.loc[df['gender'].eq('female'), 'admitted'].mean()
1.16 ms ± 66.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%%timeit
len(df[(df['gender']=='female') & (df['admitted'])])/(len(df[df['gender']=='female']))
3.45 ms ± 428 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%%timeit
df.groupby('gender').get_group('female')[df['admitted'] == True].count()/len(df.groupby('gender').get_group('female'))
10.3 ms ± 718 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%%timeit
len(df.query("gender == 'female' & admitted"))/len(df.query("gender == 'female'"))
11.1 ms ± 604 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Это время для образца DataFrame Я думаю, что производительность может сильно варьироваться в зависимости от форма вашего DataFrame. Хотя я искренне верю, что предлагаемый мною метод в большинстве случаев будет самым быстрым, помимо обеспечения простого и понятного синтаксиса.

...