добавить столбец с подсчетом по ограничению

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

Фрейм данных:

    id racecourse going distance runners draw draw_bias
0   253375  178 Standard    7.0 13  2   0.50
1   253375  178 Standard    7.0 13  11  0.25
2   253375  178 Standard    7.0 13  12  1.00
3   253376  178 Standard    6.0 12  2   1.00
4   253376  178 Standard    6.0 12  8   0.50
... ... ... ... ... ... ... ...
378867  4802789 192 Standard    7.0 16  11  0.50
378868  4802789 192 Standard    7.0 16  16  0.10
378869  4802790 192 Standard    7.0 16  1   0.25
378870  4802790 192 Standard    7.0 16  3   0.50
378871  4802790 192 Standard    7.0 16  8   1.00
378872 rows × 7 columns

Мне нужно добавить новый столбец с подсчетом уникальных гонок (id) в соответствии с условиями, определенными ниже. Этот код работает так, как ожидалось, но он ооочень медленный ….

df['race_count'] = None
for i, row in df.iterrows():
  df.at[i, 'race_count'] = df.loc[(df.racecourse==row.racecourse)&(df.going==row.going)&(df.distance==row.distance)&(df.runners==row.runners), 'id'].nunique()

1 ответ
1

Извините, это не полное решение, просто идея.

В Pandas вы можете разделить фрейм данных на подгруппы на основе одной или нескольких переменных группировки, используя groupby метод. Затем вы можете применить операцию (в данном случае nunique) в каждую из подгрупп:

df.groupby(['racecourse', 'going', 'distance', 'runners'])['id'].nunique()

Это должно дать вам количество гонок с одинаковыми характеристиками (ипподром, бег, …), но уникальными значениями для id.

Что наиболее важно, это должно быть намного быстрее, чем цикл по строкам, особенно для больших фреймов данных.


РЕДАКТИРОВАТЬ:

Вот полное решение, также включающее комбинацию с исходным фреймом данных (благодаря Ojdo для предложения join/merge)

race_count = df.groupby(['racecourse', 'going', 'distance', 'runners'])['id'].nunique()
race_count.name="race_count"
df.merge(race_count, on=['racecourse', 'going', 'distance', 'runners'])

Удобно, merge транслирует ценности в race_count ко всем рядам df на основе значений в столбцах, указанных on параметр.

Это выводит:

        id  racecourse     going  distance  runners  draw  draw_bias  race_count  
0   253375         178  Standard       7.0       13     2       0.50           1  
1   253375         178  Standard       7.0       13    11       0.25           1  
2   253375         178  Standard       7.0       13    12       1.00           1  
3   253376         178  Standard       6.0       12     2       1.00           1  
4   253376         178  Standard       6.0       12     8       0.50           1  
5  4802789         192  Standard       7.0       16    11       0.50           2  
6  4802789         192  Standard       7.0       16    16       0.10           2  
7  4802790         192  Standard       7.0       16     1       0.25           2  
8  4802790         192  Standard       7.0       16     3       0.50           2  
9  4802790         192  Standard       7.0       16     8       1.00           2 

  • 1

    И чтобы завершить эту мысль, оставшийся шаг «объединить», просто установите индекс этого результата в нужный столбец, и join это с оригиналом. (Общий узор называется сплит-применить-комбинировать, и часто это хороший способ выразить операции.)

    – ойдо

  • Да, хороший звонок. Честно говоря, у меня были проблемы с хорошей реализацией для объединения результатов (количества уникальных элементов) с исходным фреймом данных. df.

    – Флурш

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *