É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 Réponses :
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)
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.
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
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.
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')
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?