панды, как это значить - PullRequest
       17

панды, как это значить

0 голосов
/ 02 октября 2019

введите описание изображения здесь

мне нужно для расчета средней исторической оценки (test ['score_avg']) группы по 'Season' 'T1_TeamID', но мой код очень медленный. Я не знаком с пандами. Как я могу это исправить?

test['score_avg'] = "NaN"
for i in range(0,len(test)):
    if test['DayNum'][i] > 1:
        tmp_sc = test.loc[test.DayNum<test['DayNum'][i]].reset_index(drop=True).groupby(["Season", 'T1_TeamID'])['score'].agg([np.mean]).reset_index()
        test['score_avg'][i] = tmp_sc.loc[(tmp_sc.T1_TeamID==test['T1_TeamID'][i])&(tmp_sc.Season==test['Season'][i])].reset_index(drop=True)['mean'][0]
    else:
        test['score_avg'][i] = "NaN"

тестовый фрейм данных выглядит следующим образом:

  |id| T1_TeamID | score | Season | DayNum | score_avg |
  | 1|          1|     50|    2018|       1|        NaN|
  | 2|          2|     60|    2018|       1|        NaN|
  | 3|          3|     70|    2018|       1|        NaN|
  | 4|          1|     60|    2018|       2|        50 |
  | 5|          2|     70|    2018|       2|        60 |
  | 6|          3|     80|    2018|       2|        70 |
  | 7|          1|     70|    2018|       3|        55 |
  | 8|          2|     80|    2018|       3|        65 |
  | 9|          3|     90|    2018|       3|        75 |
  |10|          1|     60|    2019|       1|        NaN|
  |11|          2|     70|    2019|       1|        NaN|
  |12|          3|     80|    2019|       1|        NaN|
  |13|          1|     70|    2019|       2|        60 |
  |14|          2|     80|    2019|       2|        70 |
  |15|          3|     90|    2019|       2|        80 |
  |16|          1|     80|    2019|       3|        65 |
  |17|          2|     90|    2019|       3|        75 |
  |18|          3|    100|    2019|       3|        85 |
  |19|          1|     90|    2019|       4|        70 |
  |20|          2|    100|    2019|       4|        80 |
  |21|          3|    110|    2019|       4|        90 |

введите описание изображения здесь


не средний счет каждой команды в этом году.

- средний счет каждой команды до сегодняшнего дня в этом году.

Если команда 1 - первая игра, это не было раньше. Средняя оценка "NaN". (строка 0, id 1)

До 1 команды была игра, средний балл 50. (строка 3, идентификатор 4)

score_avg [0] = "NaN"

score_avg [3] = 50

score_avg [6] = (50 + 60) /2


Я пытался изменить это

test['score_avg'] =  np.where(test['DayNum'] > 1,test.loc[test.DayNum<test['DayNum']].reset_index(drop=True).groupby(["Season", 'T1_TeamID'])['score'].agg([np.mean]).reset_index().loc[(test.T1_TeamID==test['T1_TeamID'])&(test.Season==test['Season'])].reset_index(drop=True)['mean'][0],"NaN")

KeyError: 0

IndexError: индекс вне границ

test['score_avg'] =  np.where(test['DayNum'] > 1,test.loc[test.DayNum<test['DayNum']].reset_index(drop=True).groupby(["Season", 'T1_TeamID'])['score'].agg([np.mean]).reset_index().loc[(test.T1_TeamID==test['T1_TeamID'])&(test.Season==test['Season'])].reset_index(drop=True)['mean'],"NaN")

ValueError:операнды не могут быть переданы вместе с фигурами (21,) (0,) ()

1 Ответ

0 голосов
/ 02 октября 2019

Я думаю, что вы ищете это. Надеюсь, это поможет.

import pandas as pd

data = dict()

data['T1_TeamID'] = [1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3]

data['score'] = [50,60,70,60,70,80,70,80,90,60,70,80,70,80,90,80,90,100,90,100,110]

data['Season'] = [2018,2018,2018,2018,2018,2018,2018,2018,2019,2019,2019,2019,2019,2019,2019,2019,2019,2019,2019,2019,2019,]

#create dataframe
df = pd.DataFrame(data)
print('df-----')
print(df)

#groupby
df_gr = df.groupby(['T1_TeamID','Season']).agg({'score':'mean'})
print('after group by-----')
print(df_gr)

#refer to this example if you want to retrieve a score
team_id = 2
year = 2019
to_search = df_gr.loc[(df_gr.index.get_level_values('T1_TeamID')==team_id)&(df_gr.index.get_level_values('Season')==year)]

print('the row to search-----')
print(to_search)
print('the value-----')
print(to_search['score'].iloc[0])

Вывод

df-----
    T1_TeamID  score  Season
0           1     50    2018
1           2     60    2018
2           3     70    2018
3           1     60    2018
4           2     70    2018
5           3     80    2018
6           1     70    2018
7           2     80    2018
8           3     90    2019
9           1     60    2019
10          2     70    2019
11          3     80    2019
12          1     70    2019
13          2     80    2019
14          3     90    2019
15          1     80    2019
16          2     90    2019
17          3    100    2019
18          1     90    2019
19          2    100    2019
20          3    110    2019
after group by-----
                  score
T1_TeamID Season
1         2018       60
          2019       75
2         2018       70
          2019       85
3         2018       75
          2019       94
the row to search-----
                  score
T1_TeamID Season
2         2019       85
the value-----
85

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

import pandas as pd
from numpy import nan as NaN

data = dict()

data['T1_TeamID'] = [1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3]

data['score'] = [50,60,70,60,70,80,70,80,90,60,70,80,70,80,90,80,90,100,90,100,110]

data['avg_score'] = [NaN,NaN,NaN,50,60,70,55,65,75,NaN,NaN,NaN,60,70,80,65,75,85,70,80,90]

data['Season'] = ['2018','2018','2018','2018','2018','2018','2018','2018','2019','2019','2019','2019','2019','2019','2019','2019','2019','2019','2019','2019','2019']

data['DayNum'] = ['1','1','1','2','2','2','3','3','3','1','1','1','2','2','2','3','3','3','4','4','4']

#create dataframe
df = pd.DataFrame(data)
df.sort_values(by=['T1_TeamID','Season','DayNum'],inplace=True)
print('df-----')
print(df)

#groupby
df_gr = df.groupby(['T1_TeamID'])['score'].expanding().mean()
print('after group by-----')
print(df_gr)

#tidying the output
print('final dataframe-----')
df['running_avg'] = pd.DataFrame(df_gr).reset_index()['score']
print(df)

Вывод

df-----
    T1_TeamID  score  avg_score Season DayNum
0           1     50        NaN   2018      1
3           1     60       50.0   2018      2
6           1     70       55.0   2018      3
9           1     60        NaN   2019      1
12          1     70       60.0   2019      2
15          1     80       65.0   2019      3
18          1     90       70.0   2019      4
1           2     60        NaN   2018      1
4           2     70       60.0   2018      2
7           2     80       65.0   2018      3
10          2     70        NaN   2019      1
13          2     80       70.0   2019      2
16          2     90       75.0   2019      3
19          2    100       80.0   2019      4
2           3     70        NaN   2018      1
5           3     80       70.0   2018      2
11          3     80        NaN   2019      1
14          3     90       80.0   2019      2
8           3     90       75.0   2019      3
17          3    100       85.0   2019      3
20          3    110       90.0   2019      4
after group by-----
T1_TeamID
1          0     50.000000
           3     55.000000
           6     60.000000
           9     60.000000
           12    62.000000
           15    65.000000
           18    68.571429
2          1     60.000000
           4     65.000000
           7     70.000000
           10    70.000000
           13    72.000000
           16    75.000000
           19    78.571429
3          2     70.000000
           5     75.000000
           11    76.666667
           14    80.000000
           8     82.000000
           17    85.000000
           20    88.571429
Name: score, dtype: float64
final dataframe-----
    T1_TeamID  score  avg_score Season DayNum  running_avg
0           1     50        NaN   2018      1      50.000000
3           1     60       50.0   2018      2      60.000000
6           1     70       55.0   2018      3      68.571429
9           1     60        NaN   2019      1      70.000000
12          1     70       60.0   2019      2      75.000000
15          1     80       65.0   2019      3      75.000000
18          1     90       70.0   2019      4      82.000000
1           2     60        NaN   2018      1      55.000000
4           2     70       60.0   2018      2      62.000000
7           2     80       65.0   2018      3      60.000000
10          2     70        NaN   2019      1      70.000000
13          2     80       70.0   2019      2      78.571429
16          2     90       75.0   2019      3      76.666667
19          2    100       80.0   2019      4      85.000000
2           3     70        NaN   2018      1      60.000000
5           3     80       70.0   2018      2      65.000000
11          3     80        NaN   2019      1      72.000000
14          3     90       80.0   2019      2      70.000000
8           3     90       75.0   2019      3      65.000000
17          3    100       85.0   2019      3      80.000000
20          3    110       90.0   2019      4      88.571429

Edit3: Вот так я быстро создаю ваш столбец avg_score. Я также исправил ваши неправильные вычисления для avg_score для индексов 8 и 17

import pandas as pd
from numpy import nan as NaN

#create the data
data = dict()
data['T1_TeamID'] = [1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3]
data['score'] = [50,60,70,60,70,80,70,80,90,60,70,80,70,80,90,80,90,100,90,100,110]
data['Season'] = ['2018','2018','2018','2018','2018','2018','2018','2018','2019','2019','2019','2019','2019','2019','2019','2019','2019','2019','2019','2019','2019']
data['DayNum'] = ['1','1','1','2','2','2','3','3','3','1','1','1','2','2','2','3','3','3','4','4','4']

#create the dataframe
df = pd.DataFrame(data)
df.sort_values(by=['T1_TeamID','Season','DayNum'],inplace=True)

#groupby cumulative average and shift by one
temp = df.groupby(['T1_TeamID','Season'])['score'].expanding().mean().groupby(['T1_TeamID','Season']).shift()

#reset_index and renaming
temp = temp.reset_index().set_index('level_2')['score'].rename_axis(None)

df['avg_score'] = temp

print(df)

Вывод

    T1_TeamID  score Season DayNum  avg_score
0           1     50   2018      1        NaN
3           1     60   2018      2  50.000000
6           1     70   2018      3  55.000000
9           1     60   2019      1        NaN
12          1     70   2019      2  60.000000
15          1     80   2019      3  65.000000
18          1     90   2019      4  70.000000
1           2     60   2018      1        NaN
4           2     70   2018      2  60.000000
7           2     80   2018      3  65.000000
10          2     70   2019      1        NaN
13          2     80   2019      2  70.000000
16          2     90   2019      3  75.000000
19          2    100   2019      4  80.000000
2           3     70   2018      1        NaN
5           3     80   2018      2  70.000000
11          3     80   2019      1        NaN
14          3     90   2019      2  80.000000
8           3     90   2019      3  85.000000
17          3    100   2019      3  86.666667
20          3    110   2019      4  90.000000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...