Расчет расстояния до строки с определенным значением - PullRequest
0 голосов
/ 24 сентября 2018

Я работаю над данными с пандами, в которых выполняются работы по техническому обслуживанию на месте.Техническое обслуживание проводится каждые четыре года на каждом объекте.Я хочу найти годы с момента последнего технического обслуживания на каждом объекте.Я приведу здесь только два сайта в следующем примере, но в исходном наборе данных у меня их тысячи.Мои данные охватывают только 2014–2017 годы.

Действие = 0 означает, что в этом году не было выполнено никаких действий, Действие = 1 означает, что какое-то действие было выполнено.Измерение - это показание производительности, связанное с эффектом действия.Действие может произойти в любой год.Я знаю, что если действие было выполнено в Году Y, предыдущее обслуживание было выполнено в Году Y. 4.

 Site  Year   Action  Measurement
   A   2014     0         100
   A   2015     0         150
   A   2016     1         300
   A   2017     0         80
   B   2014     0         200
   B   2015     1         250
   B   2016     0         60
   B   2017     0         110

С учетом этого набора данных;во-первых, я хочу иметь временный набор данных, подобный этому:

 Item  Year   Action  Measurement  Years_Since_Last_Action
   A   2014     0         100           2
   A   2015     0         150           3
   A   2016     1         300           4
   A   2017     0         80            1
   B   2014     0         200           3
   B   2015     1         250           4
   B   2016     0         60            1
   B   2017     0         110           2

Затем я хочу иметь:

Years_Since_Last_Action         Mean_Measurement
        1                            70
        2                            105
        3                            175
        4                            275

Заранее спасибо!

Ответы [ 3 ]

0 голосов
/ 24 сентября 2018

Как насчет:

delta_year = df.loc[df.groupby("Site")["Action"].transform("idxmax"), "Year"].values
years_since = ((df.Year - delta_year) % 4).replace(0, 4)
df["Years_Since_Last_Action"] = years_since

out = df.groupby("Years_Since_Last_Action")["Measurement"].mean().reset_index()
out = out.rename(columns={"Measurement": "Mean_Measurement"})

, что дает мне

In [230]: df
Out[230]: 
  Site  Year  Action  Measurement  Years_Since_Last_Action
0    A  2014       0          100                        2
1    A  2015       0          150                        3
2    A  2016       1          300                        4
3    A  2017       0           80                        1
4    B  2014       0          200                        3
5    B  2015       1          250                        4
6    B  2016       0           60                        1
7    B  2017       0          110                        2

In [231]: out
Out[231]: 
   Years_Since_Last_Action  Mean_Measurement
0                        1                70
1                        2               105
2                        3               175
3                        4               275
0 голосов
/ 24 сентября 2018

Во-первых, постройте ваше промежуточное звено, используя groupby, *fill и небольшую арифметику.

v = (df.Year
       .where(df.Action.astype(bool))
       .groupby(df.Site)
       .ffill()
       .bfill()
       .sub(df.Year))
df['Years_Since_Last_Action'] = np.select([v > 0, v < 0], [4 - v, v.abs()], default=4)

df
  Site  Year  Action  Measurement  Years_Since_Last_Action
0    A  2014       0          100                      2.0
1    A  2015       0          150                      3.0
2    A  2016       1          300                      4.0
3    A  2017       0           80                      1.0
4    B  2014       0          200                      3.0
5    B  2015       1          250                      4.0
6    B  2016       0           60                      1.0
7    B  2017       0          110                      2.0

Далее,

df.groupby('Years_Since_Last_Action', as_index=False).Measurement.mean()

   Years_Since_Last_Action  Measurement
0                      1.0           70
1                      2.0          105
2                      3.0          175
3                      4.0          275
0 голосов
/ 24 сентября 2018

Ваш первый вопрос

s=df.loc[df.Action==1,['Site','Year']].set_index('Site') # get all year have the action and map back to the whole dataframe
df['Newyear']=df.Site.map(s.Year)
s1=df.Year-df.Newyear
df['action since last year']=np.where(s1<=0,s1+4,s1)# using np.where get the condition
df
Out[167]: 
  Site  Year  Action  Measurement  Newyear  action since last year
0    A  2014       0          100     2016                       2
1    A  2015       0          150     2016                       3
2    A  2016       1          300     2016                       4
3    A  2017       0           80     2016                       1
4    B  2014       0          200     2015                       3
5    B  2015       1          250     2015                       4
6    B  2016       0           60     2015                       1
7    B  2017       0          110     2015                       2

Второй вопрос

df.groupby('action since last year').Measurement.mean()
Out[168]: 
action since last year
1     70
2    105
3    175
4    275
Name: Measurement, dtype: int64
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...