J'aurais dû poser la question suivante lors de la publication de ce. Comme vous pouvez le voir ci-dessous, mon df contient des valeurs consécutives identiques, c'est-à-dire 1, 2 et 3.

Date                London  Paris   Dubai   Tokyo
18/07/2017 22:35    1       2406    4348    70715
18/07/2017 22:40    1       4756    3744    3
18/07/2017 22:45    1       3988    2915    3
18/07/2017 22:50    2280    3058    2120    3
18/07/2017 22:55    2       1       1939    3
18/07/2017 23:00    2       1       2256    3
18/07/2017 23:05    2121    1       2640    2025
18/07/2017 23:10    3367    2       2202    1916
18/07/2017 23:15    3247    3       1       2
18/07/2017 23:20    2491    3       1       2
18/07/2017 23:25    2010    3       1       1560
18/07/2017 23:30    1899    3       1366    1355
18/07/2017 23:35    1992    2265    1236    1
18/07/2017 23:40    2196    4407    2       1
18/07/2017 23:45    1961    3848    2       1
18/07/2017 23:50    3       2880    2809    4565
18/07/2017 23:55    3       2143    2397    3725
19/07/2017 00:00    3       1981    3       2921
19/07/2017 00:05    3       2227    3       2131
19/07/2017 00:10    1366    2526    3       1990

Je veux détecter ces "valeurs mortes" chaque fois qu'elles sont bloquées dans un minimum de 3 lignes, puis les changer toutes avec NaN car je veux les éliminer plus tard. Avec le code de ici, je peux le faire pour la colonne Londres.

g = df.London.diff().fillna(0).ne(0).cumsum()
m = df.groupby(g).London.transform('size').ge(3)
df.loc[m,'London'] = np.nan
df.assign(grouper=g, mask=m, result=df.London)

Mais, je veux le faire aussi à d'autres (quelques 250 colonnes).

Ce qui suit est la sortie attendue, où tous les 1 et 3 sont convertis en NaN car leurs valeurs sont restées bloquées pendant au moins 3 lignes consécutives.

Date                London  Paris   Dubai   Tokyo
18/07/2017 22:35    NaN     2406    4348    70715
18/07/2017 22:40    NaN     4756    3744    NaN
18/07/2017 22:45    NaN     3988    2915    NaN
18/07/2017 22:50    2280    3058    2120    NaN
18/07/2017 22:55    2       NaN     1939    NaN
18/07/2017 23:00    2       NaN     2256    NaN
18/07/2017 23:05    2121    NaN     2640    2025
18/07/2017 23:10    3367    2       2202    1916
18/07/2017 23:15    3247    NaN     NaN     2
18/07/2017 23:20    2491    NaN     NaN     2
18/07/2017 23:25    2010    NaN     NaN     1560
18/07/2017 23:30    1899    NaN     1366    1355
18/07/2017 23:35    1992    2265    1236    NaN
18/07/2017 23:40    2196    4407    2       NaN
18/07/2017 23:45    1961    3848    2       NaN
18/07/2017 23:50    NaN     2880    2809    4565
18/07/2017 23:55    NaN     2143    2397    3725
19/07/2017 00:00    NaN     1981    NaN     2921
19/07/2017 00:05    NaN     2227    NaN     2131
19/07/2017 00:10    1366    2526    NaN     1990
0
k.ko3n 19 mars 2019 à 00:06

2 réponses

Meilleure réponse

shift en utilisant np.logical_and.reduce et np.logical_or.reduce pour créer le masque (ou un double where).

import numpy as np
import pandas as pd

Nmin = 3  # At least 2

m = pd.DataFrame(np.logical_and.reduce([(df == df.shift(i)).to_numpy() for i in range(1, Nmin)]))

df = df.where(df.where(m.to_numpy()).bfill(limit=Nmin-1).isnull())
#df = df.mask(np.logical_or.reduce([m.shift(-i).fillna(False).to_numpy() for i in range(Nmin)]))

Sortie: df

                Date  London   Paris   Dubai    Tokyo
0   18/07/2017-22:35     NaN  2406.0  4348.0  70715.0
1   18/07/2017-22:40     NaN  4756.0  3744.0      NaN
2   18/07/2017-22:45     NaN  3988.0  2915.0      NaN
3   18/07/2017-22:50  2280.0  3058.0  2120.0      NaN
4   18/07/2017-22:55     2.0     NaN  1939.0      NaN
5   18/07/2017-23:00     2.0     NaN  2256.0      NaN
6   18/07/2017-23:05  2121.0     NaN  2640.0   2025.0
7   18/07/2017-23:10  3367.0     2.0  2202.0   1916.0
8   18/07/2017-23:15  3247.0     NaN     NaN      2.0
9   18/07/2017-23:20  2491.0     NaN     NaN      2.0
10  18/07/2017-23:25  2010.0     NaN     NaN   1560.0
11  18/07/2017-23:30  1899.0     NaN  1366.0   1355.0
12  18/07/2017-23:35  1992.0  2265.0  1236.0      NaN
13  18/07/2017-23:40  2196.0  4407.0     2.0      NaN
14  18/07/2017-23:45  1961.0  3848.0     2.0      NaN
15  18/07/2017-23:50     NaN  2880.0  2809.0   4565.0
16  18/07/2017-23:55     NaN  2143.0  2397.0   3725.0
17  19/07/2017-00:00     NaN  1981.0     NaN   2921.0
18  19/07/2017-00:05     NaN  2227.0     NaN   2131.0
19  19/07/2017-00:10  1366.0  2526.0     NaN   1990.0
1
ALollz 18 mars 2019 à 21:32

Si votre code fonctionne correctement et rapidement, itérez-le simplement sur les colonnes :

for col in df.columns:
    g = df.[col].diff().fillna(0).ne(0).cumsum()
    # and so on...
0
Poe Dator 18 mars 2019 à 21:14