1
votes

Ajout de nouvelles colonnes à une trame de données en fonction de la valeur d'une autre colonne

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)


0 commentaires

3 Réponses :


1
votes

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'


3 commentaires

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



1
votes

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


0 commentaires

0
votes

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.


0 commentaires