En utilisant ceci comme point de départ:
a = [['10', '1.2', '4.2'], ['15', '70', '0.03'], ['8', '5', '0']]
df = pd.DataFrame(a, columns=['one', 'two', 'three'])
Out[8]:
one two three
0 10 1.2 4.2
1 15 70 0.03
2 8 5 0
Je veux utiliser quelque chose comme une déclaration if
au sein des pandas.
if df['one'] >= df['two'] and df['one'] <= df['three']:
df['que'] = df['one']
Fondamentalement, vérifiez chaque ligne via l'instruction if
, créez une nouvelle colonne.
Les docs disent d'utiliser .all
mais il n'y a pas d'exemple ...
Vous pouvez utiliser np.where . Si cond
est un tableau booléen et que A
et B
sont des tableaux, alors
C = np.where(cond, A, B)
définit C comme étant égal à A
où cond
est vrai, et B
où cond
est faux.
import numpy as np
import pandas as pd
a = [['10', '1.2', '4.2'], ['15', '70', '0.03'], ['8', '5', '0']]
df = pd.DataFrame(a, columns=['one', 'two', 'three'])
df['que'] = np.where((df['one'] >= df['two']) & (df['one'] <= df['three'])
, df['one'], np.nan)
les rendements
one two three que
0 10 1.2 4.2 10
1 15 70 0.03 NaN
2 8 5 0 NaN
Si vous avez plusieurs conditions, vous pouvez utiliser np.select à la place de . Par exemple, si vous souhaitez que df['que']
soit égal à df['two']
lorsque df['one'] < df['two']
, alors
conditions = [
(df['one'] >= df['two']) & (df['one'] <= df['three']),
df['one'] < df['two']]
choices = [df['one'], df['two']]
df['que'] = np.select(conditions, choices, default=np.nan)
les rendements
one two three que
0 10 1.2 4.2 10
1 15 70 0.03 70
2 8 5 0 NaN
Si nous pouvons supposer que df['one'] >= df['two']
lorsque df['one'] < df['two']
est égal à False, les conditions et les choix pourraient alors être simplifiés.
conditions = [
df['one'] < df['two'],
df['one'] <= df['three']]
choices = [df['two'], df['one']]
(L'hypothèse peut ne pas être vraie si df['one']
ou df['two']
contient des NaN.)
Notez que
a = [['10', '1.2', '4.2'], ['15', '70', '0.03'], ['8', '5', '0']]
df = pd.DataFrame(a, columns=['one', 'two', 'three'])
définit un DataFrame avec des valeurs de chaîne. Comme elles ont l’air numérique, vous feriez bien de convertir ces chaînes en floats:
df2 = df.astype(float)
Cela change cependant les résultats, puisque les chaînes comparent caractère par caractère, tandis que les flottants sont comparés numériquement.
In [61]: '10' <= '4.2'
Out[61]: True
In [62]: 10 <= 4.2
Out[62]: False
Vous pouvez utiliser .equals
pour des colonnes ou des images complètes.
df['col1'].equals(df['col2'])
Si elles sont égales, cette instruction retournera True
, sinon False
.
Vous pouvez utiliser apply () et faire quelque chose comme ça
df['que'] = df.apply(lambda x : x['one'] if x['one'] >= x['two'] and x['one'] <= x['three'] else "", axis=1)
ou si vous préférez ne pas utiliser de lambda
def que(x):
if x['one'] >= x['two'] and x['one'] <= x['three']:
return x['one']
else:
''
df['que'] = df.apply(que, axis=1)
Une solution consiste à utiliser une série booléenne pour indexer la colonne df['one']
. Cela vous donne une nouvelle colonne où les entrées True
ont la même valeur que la même ligne que df['one']
et les valeurs False
sont NaN
.
La série booléenne est simplement donnée par votre instruction if
(bien qu'il soit nécessaire d'utiliser &
au lieu de and
):
>>> df['que'] = df['one'][(df['one'] >= df['two']) & (df['one'] <= df['three'])]
>>> df
one two three que
0 10 1.2 4.2 10
1 15 70 0.03 NaN
2 8 5 0 NaN
Si vous souhaitez que les valeurs NaN
soient remplacées par d'autres valeurs, vous pouvez utiliser la méthode fillna
sur la nouvelle colonne que
. J'ai utilisé 0
au lieu de la chaîne vide ici:
>>> df['que'] = df['que'].fillna(0)
>>> df
one two three que
0 10 1.2 4.2 10
1 15 70 0.03 0
2 8 5 0 0
Placez chaque condition entre parenthèses, puis utilisez l'opérateur &
pour combiner les conditions:
df.loc[(df['one'] >= df['two']) & (df['one'] <= df['three']), 'que'] = df['one']
Vous pouvez remplir les lignes qui ne correspondent pas en utilisant simplement ~
(l'opérateur "not") pour inverser la correspondance:
df.loc[~ ((df['one'] >= df['two']) & (df['one'] <= df['three'])), 'que'] = ''
Vous devez utiliser &
et ~
plutôt que and
et not
car les opérateurs &
et ~
fonctionnent élément par élément.
Le résultat final:
df
Out[8]:
one two three que
0 10 1.2 4.2 10
1 15 70 0.03
2 8 5 0
Je pense que l'intuition la plus proche de l'OP est une déclaration inline si:
df['que'] = (df['one'] if ((df['one'] >= df['two']) and (df['one'] <= df['three']))