2 votes

Python shift() de la même colonne comme dans Excel avec des dates

Je veux créer une colonne 'target_start' en python :

id

iniciar

fin

diff

Début de la cible

12220

1999-11-22

2008-08-31

3515

1999-11-22

12220

2018-04-16

2019-09-15

1

2018-04-16

12220

2019-09-16

2019-11-30

1

2018-04-16

12220

2019-12-01

2020-03-31

1

2018-04-16

12220

2020-04-01

2020-06-30

-711

2018-04-16

11132

2018-07-20

2019-09-15

1

2018-07-20

11132

2019-09-16

2021-01-01

-44197

2018-07-20

Ce problème est facile à résoudre dans Excel :

enter image description here

mais je ne sais pas, comment puis-je faire cela dans pyton : La première ligne cible est "1", ensuite :

df.loc[df.index==0,'target_start']= df['start']

J'ai essayé ce code, mais ça ne marche pas :

import pandas as pd
df=pd.read_excel('./Shift.xlsx')

#if id != id.shift(1) then target_start = start
df.loc[df['id'] != df['id'].shift(1), 'target_start'] = df['start']

#elif: diff != 1 then target_start = start
df.loc[df['diff'].shift(1) != 1, 'target_start'] = df['start']

#else: target_start = target_start.shift(1)
df.loc[(df.index != 0) & (df['id'] == df['id'].shift(1)) & (df['diff'].shift(1) == 1), 'target_start']=df['target_start'].shift(1)

print(df)

Le résultat est :

id

iniciar

fin

diff

Début de la cible

12220

1999-11-22

2008-08-31

3515

1999-11-22

12220

2018-04-16

2019-09-15

1

2018-04-16

12220

2019-09-16

2019-11-30

1

2018-04-16

12220

2019-12-01

2020-03-31

1

NaT

12220

2020-04-01

2020-06-30

-711

NaT

11132

2018-07-20

2019-09-15

1

2018-07-20

11132

2019-09-16

2021-01-01

-44197

2018-07-20

Quelqu'un sait comment résoudre ce problème ? Merci d'avance !

1voto

Pankaj Joshi Points 736

Voici comment je vais mettre en œuvre votre formule Excel (que vous avez mise en évidence) :

df.start = pd.to_datetime(df.start)
df.end = pd.to_datetime(df.end)
df.target_start = pd.to_datetime(df.target_start)

df["id_shift"] = df.id.shift()

target_start = [df.iloc[0, 1]]

for i in range(1, df.shape[0]):
    print(i)
    if df.iloc[i, 0] != df.iloc[i - 1, 0]:
        target_start.append(df.iloc[i, 1])
    else:
        if df.iloc[i, 3] == 1:
            target_start.append(df.iloc[i, 1])
        else:
            target_start.append(target_start[i - 1])

df["target_start"] = target_start
del df["id_shift"]

Il génère le resutl suivant :

id  start   end         diff                 target_start
0   12220   1999-11-22  2008-08-31  3515    1999-11-22
1   12220   2018-04-16  2019-09-15  1       2018-04-16
2   12220   2019-09-16  2019-11-30  1       2019-09-16
3   12220   2019-12-01  2020-03-31  1       2019-12-01
4   12220   2020-04-01  2020-06-30  -711    2019-12-01
5   11132   2018-07-20  2019-09-15  1       2018-07-20
6   11132   2019-09-16  2021-01-01  -44197  2018-07-20

1voto

Bela Points 45

Merci @quest ! C'est fantastique :)

J'ai réparé une chose après l'autre :

        else:
            if df.iloc[i-1, 3] != 1:
                target_start.append(df.iloc[i, 1])

Donc le code parfait est :

df.start = pd.to_datetime(df.start)
df.end = pd.to_datetime(df.end)
df.target_start = pd.to_datetime(df.target_start)

df["id_shift"] = df.id.shift()

target_start = [df.iloc[0, 1]]

for i in range(1, df.shape[0]):
    #print(i)
    if df.iloc[i, 0] != df.iloc[i - 1, 0]:
        target_start.append(df.iloc[i, 1])
    else:
        if df.iloc[i-1, 3] != 1:
            target_start.append(df.iloc[i, 1])
        else:
            target_start.append(target_start[i - 1])

df["target_start"] = target_start
del df["id_shift"]
df.head(7)

Merci encore ! Vous m'avez beaucoup aidé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X