1
votes

Comment déterminer l'état dans une colonne en fonction de deux autres colonnes booléennes pour une trame de données Pandas de séries temporelles?

Étant donné le premier dataframe, existe-t-il un moyen avec les pandas . shift () , . diff () , . Replace () , ou . apply () pour accomplir la colonne D du deuxième dataframe ou sinon, comment cela pourrait-il être fait?

C'est utile de savoir qu'en itérant de haut en bas, les lignes de la colonne D restent Vrai une fois qu'une ligne de la colonne B est Vrai et seulement tant qu'aucun Vrai n'est rencontré dans la colonne C. Il s'agit essentiellement de déterminer l'état basé sur B et C. p>

def determine_state(df,x,y,z):
  """Given a dataframe where columns x and y are Booleans
  displaying the entering and exit of a Boolean state, create 
  a third column that displays the state."""

  # set column z to False
  df[z] = False

  # filter column x for True and set z to True
  df.loc[df[x], z] = True

  # filter column y for True and set z to False
  df.loc[df[y], z] = False

  # forward fill on z
  df[z] = df[z].ffill(axis=0)

  return df

Solutions fonctionnalisées

@jezrael (import numpy comme np requis)

def determine_state(df,x,y,z):
  """Given a dataframe where columns x and y are Booleans
  displaying the entering and exit of a Boolean state, create 
  a third column that displays the state."""

  # use numpy.select with forward filling missing values 
  df[z] = np.select([df[x], df[y]], [True, False], None)

  # replace first Nones by False if exist
  df[z] = df[z].ffill().fillna(False)

  return df

@ run-out

XXX


3 commentaires

Je ne comprends pas la logique derrière D.Un peu plus d'explications pourrait aider


@zero De haut en bas, lorsque True est rencontré dans B, D devient True et reste True. Lorsque True est rencontré en C, D devient False et reste False.


Peut-être que cela pourrait être accompli en référençant les lignes précédentes dans une application?


3 Réponses :


1
votes

Première colonne de filtre 'B' pour Vrai et définissez 'D' sur Vrai

df['D'].fillna(False, inplace=True)

Ensuite, faites de même pour 'C' mais définissez-le sur Faux

df['D'] = df['D'].ffill(axis=0)


5 commentaires

Cela fournit une réponse correcte. Je n'ai pas fourni techniquement le meilleur exemple. Sur la base de cette réponse, comment rempliriez-vous le NaN dans la colonne D si True ne se produisait pas avant la deuxième ligne de la colonne B?


Je suppose que logiquement, tout NaN serait automatiquement faux.


Ouais, vous auriez juste des NaN là-bas, donc vous seriez prêt.


@jezrael est la solution préférée.


Merci pour votre réponse rapide et efficace. J'ai voté à la hausse.



3
votes

Utilisez numpy.select avec les valeurs manquantes de remplissage avant et le dernier remplacement des Aucun par False s'il existe:

import numpy as np

df['D'] = np.select([df['B'], df['C']], [True, False], None)
df['D'] = df['D'].ffill().fillna(False)
print (df)
                     A      B      C      D
2019-05-04 00:15:00  1   True  False   True
2019-05-04 00:30:00  2  False  False   True
2019-05-04 00:45:00  2  False  False   True
2019-05-04 01:00:00  3  False   True  False
2019-05-04 01:15:00  1  False  False  False
2019-05-04 01:30:00  2  False  False  False
2019-05-04 01:45:00  2   True  False   True
2019-05-04 02:00:00  3  False  False   True
2019-05-04 02:15:00  1  False  False   True
2019-05-04 02:30:00  2  False   True  False
2019-05-04 02:45:00  2  False  False  False
2019-05-04 02:00:00  3  False  False  False


2 commentaires

Je suppose que cela nécessite également d'importer numpy en tant que np, ce qui est une formalité car les pandas l'utilisent déjà dans les coulisses. Il pourrait également être référencé avec pd.np.select ...


@Liquidgenius - Oui, c'est 2 solutions possibles - j'aime plus d'abord.



0
votes

Utilisez ci-dessous:

df['D'] = np.nan
df.loc[ df['B'] == True , 'D'] = True
df.loc[ df['C'] == True , 'D'] = False
df.fillna(method='ffill')


0 commentaires