J'ai lu de nombreuses questions à ce sujet, mais je ne savais pas comment appliquer ces solutions à mon propre problème. Je suppose que je dois utiliser df.apply ou df.assign mais je ne comprends pas comment même après avoir lu la documentation
Voici mes données: p >
Position 0 open 1 open 2 moving 3 moving 4 moving 5 close 6 close 7 close 8 close 9 close 10 moving 11 moving 12 moving 13 open 14 open 15 moving 16 moving 17 open
Il est ouvert lorsque switchopen == True & switchclose == False
Il est fermé lorsque switchopen == False & switchclose == True
ça bouge quand switchopen == False & switchclose == False
Ma solution actuelle est la suivante:
df['Close'] = (df.switchclose == True & df.switchopen == False) df['Open'] = (df.switchclose == False & df.switchopen == False) df['Moving'] = (df.switchclose == False & df.switchopen == False)
Ce qui me donne ce que je veux mais je cherche une meilleure solution comme:
dfopen = df[(df.switchclose == False) & (df.switchopen == True)] dfopen['Open'] = 'open' dfclose = df[(df.switchclose == True) & (df.switchopen == False)] dfclose['Moving'] = 'close' dfmoving = df[(df.switchclose == False) & (df.switchopen == False)] dfmoving['Close'] = 'moving' dfs = [dfopen, dfclose, dfmoving] dfz = pd.concat(dfs, sort= False) dfz = dfz.sort_index(ascending=True) dfz['Position'] = dfz['Position'].fillna(dfz['Open']) dfz['Position'] = dfz['Position'].fillna(dfz['Close']) print(dfz['Position'])
Et puis utiliser le . fillna .
il serait préférable qu'il y ait une solution où cette étape ne serait même pas nécessaire
Le résultat attendu est le suivant:
d = {'switchopen': [True, True, False, False, False, False, False, False, False, False, False, False, False, True, True, False, False, True ],
'switchclose': [ False, False, False, False, False, True, True, True, True, True, False, False, False, False, False, False, False, False]}
df = pd.DataFrame(data=d)
3 Réponses :
Compte tenu de vos exigences logiques et de vos attentes de sortie, cela devrait fonctionner
df.loc[(df['switchopen'] == True) & (df['switchclose'] == False), 'Position'] = 'open' df.loc[(df['switchopen'] == False) & (df['switchclose'] == True), 'Position'] = 'closed' df.loc[(df['switchopen'] == False) & (df['switchclose'] == False), 'Position'] = 'moving'
Une solution si simple, je me sens stupide de ne pas avoir pensé à utiliser df.loc . J'accepte que cela soit dans 2 minutes
Heureux de pouvoir aider;) @MartijnvanAmsterdam
Les booléens ne sont pas nécessaires, les données contiennent déjà des booléens. Pas besoin de les ajouter pour utiliser des opérateurs logiques
Pour plusieurs conditions, vous pouvez utiliser np.select . Vous pouvez commencer par définir les conditions:
df['position'] = np.select([c1,c2, c3], ['open','closed', 'moving'])
switchopen switchclose position
0 True False open
1 True False open
2 False False moving
3 False False moving
4 False False moving
5 False True closed
6 False True closed
7 False True closed
8 False True closed
9 False True closed
10 False False moving
11 False False moving
12 False False moving
13 True False open
14 True False open
15 False False moving
16 False False moving
17 True False open
Et sur le bon terme spécifiez la liste de sélection à partir de laquelle les éléments de sortie sont extraits:
c1 = df.switchopen & ~df.switchclose c2 = ~df.switchopen & df.switchclose c3 = ~df.switchopen & ~df.switchclose
J'aime np.where. Voici la solution:
import numpy as np
df.loc[:,'position1'] = np.where((df['switchopen'] == True) & (df['switchclose'] == False), 'open',
np.where((df['switchopen'] == False) & (df['switchclose'] == True), 'closed',
np.where((df['switchopen'] == False) & (df['switchclose'] == False), 'moving',
np.nan)))
Comme vous pouvez le voir, vous ne pouvez définir le NaN pour aucune des conditions.