Добавить новый столбец в фрейм данных, где значения зависят от предыдущих значений строки в этом же столбце - PullRequest
0 голосов
/ 06 ноября 2018

У меня есть фрейм данных (df), где голова выглядит так:

  BB   NEW_DATE     PICKED
1123 03/10/2018 03/10/2018
1123 04/10/2018 04/10/2018
1123 05/10/2018 05/10/2018
1123 09/10/2018 09/10/2018
1123 04/01/2013 01/04/2013
1123 07/01/2013 07/01/2013
1123 08/01/2013 08/01/2013

Я пытаюсь добавить новый столбец с именем FINAL, чьи значения частично зависят от предыдущих значений строки FINAL.

if df['PICKED'] < df['FINAL'].shift(-1):
    if df['NEW_DATE'].isnumeric():
        df['FINAL'] = df['NEW_DATE'] 
    else:
        df['FINAL'] = df['PICKED']
    df['FINAL'] = df['PICKED']

Для каждой строки, если PICKED меньше, чем предыдущее значение строки FINAL, то, если NEW_DATE является действительной датой, текущее значение строки FINAL равно текущему значению строки NEW_DATE, в противном случае FINAL равен равно PICKED. Если PICKED больше или равно значению предыдущих строк FINAL, тогда FINAL равно PICKED.

поэтому в приведенном выше фрейме данных столбец FINAL будет выглядеть так:

  BB     NEW_DATE       PICKED       FINAL
1123   03/10/2018   03/10/2018  03/10/2018
1123   04/10/2018   04/10/2018  04/10/2018
1123   05/10/2018   05/10/2018  05/10/2018
1123   09/10/2018   09/10/2018  09/10/2018
1123   04/01/2013   01/04/2013  04/01/2013
1123   07/01/2013   07/01/2013  07/01/2013
1123   08/01/2013   08/01/2013  08/01/2013

Я безуспешно пытался закодировать это с помощью:

df['FINAL'] = np.where(df['PICKED'] < df['FINAL'].shift(-1), df.NEW_DATE.fillna(df.DATE), df['PICKED'])

Я также пробовал:

for row in df.iterrows:

    if index == 0 :
        row['FINAL'] = row['NEW_DATE']
    else:

        if row['PICKED'] < row['FINAL'].shift(-1):
            if isinstance(row['NEW_DATE'], pd.DatetimeIndex):
                row['FINAL'] = row['NEW_DATE']
            else:
                row['FINAL'] = row['PICKED']
        else:
            row['FINAL'] = row['PICKED']

но я получаю ошибку: TypeError: 'method' object is not iterable

1 Ответ

0 голосов
/ 06 ноября 2018

Я не мог придумать пути без цикла для, так что вот один из способов.

# Initalise the first value of FINAL that will be the previous value 
# in the first iteration of the loop
prev_final = df.loc[0,'PICKED'] 

#create a list containing the data to create the column FINAL after
list_final = [prev_final] 

# loop over the rows with itertuples, not the first row as it has been take care of before
for new_date, picked in df.loc[1:,['NEW_DATE','PICKED']].itertuples(index=False):

    # check the two conditions at once as if both are not met, then the value in FINAL is from PICKED
    if (picked < prev_final) & isinstance(new_date, pd.datetime):
        # add the value from NEW_DATE
        list_final.append(new_date) 
        # and update the prev_final for the next iteration of the loop
        prev_final = new_date 

    else: # same idea if conditions not met
        list_final.append(picked)
        prev_final = picked

#outside of the loop, create the column with the list
df['FINAL'] = list_final

print(df)
     BB   NEW_DATE     PICKED      FINAL
0  1123 2018-03-10 2018-03-10 2018-03-10
1  1123 2018-04-10 2018-04-10 2018-04-10
2  1123 2018-05-10 2018-05-10 2018-05-10
3  1123 2018-09-10 2018-09-10 2018-09-10
4  1123 2013-04-01 2013-01-04 2013-04-01
5  1123 2013-07-01 2013-07-01 2013-07-01
6  1123 2013-08-01 2013-08-01 2013-08-01
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...