自事件以来的岁月

时间:2018-10-06 16:24:35

标签: python pandas

我正在处理带有熊猫的数据集,其中在某个位置进行了维护工作。维护是随机进行的,有时是一年,有时甚至永远不会。如果要在每个站点上执行维护操作,我想查找自该站点上次维护操作以来的时间。一个站点可以有多个动作,并且动作的发生是随机的。对于第一个操作之前的年份,由于该信息不在数据集中,因此无法知道自操作以来的年份。 在下面的示例中,我仅给出两个站点,但是在原始数据集中,我有成千上万个站点。我的数据仅涵盖2014年至2017年。

Action = 0表示当年未执行任何操作,Action = 1表示已执行某些操作。度量是与动作效果相关的性能读数。该行动可以在任何一年发生。

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

给出该数据集;我想要一个像这样的数据集:

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

请注意,对于站点B而言,2015年被过滤掉了,因为该年早于该站点的第一次行动。

非常感谢!

2 个答案:

答案 0 :(得分:0)

这是我的处理方法:

import pandas as pd

from io import StringIO

import numpy as np

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

ss = StringIO(s)

df = pd.read_csv(ss, sep=r"\s+")


df_maintain = df[df.Action==1][['Site', 'Year']]
df_maintain.reset_index(drop=True, inplace=True)
df_maintain

def find_last_maintenance(x):
    df_temp = df_maintain[x.Site == df_maintain.Site]

    gap = [0]

    for ind, row in df_temp.iterrows():

        if (x.Year >= row['Year']):
            gap.append(x.Year - row['Year'] + 1)



    return gap[-1]

df['Gap'] = df.apply(find_last_maintenance, axis=1)

df = df[df.Gap !=0]

enter image description here

这将生成所需的输出。

答案 1 :(得分:0)

我自己编写了代码。杂乱无章,但却为我完成了工作。 :) 该解决方案假定df_select具有整数索引。

df_select = (df_select[df_select['Site'].map((df_select.groupby('Site')['Action'].max() == 1))])
years_since_action = pd.Series(dtype='int64')
gbo = df_select.groupby('Site')
for (key,group) in gbo:
    indices_with_ones = group[group['Action']==1].index
    indices = group.index
    group['Years_since_action'] = 0
    group.loc[indices_with_ones,'Years_since_action'] = 1

    for idx_with_ones in indices_with_ones.sort_values(ascending=False):
        for idx in indices:
            if group.loc[idx,'Years_since_action']==0:
                if idx>idx_with_ones:
                    group.loc[idx,'Years_since_action'] = idx - idx_with_ones + 1


    years_since_action = years_since_action.append(group['Years_since_action'])

df_final = pd.merge(df_select,pd.DataFrame(years_since_action),how='left',left_index=True,right_index=True)