Étant donné la mise à jour de pandas 0.20.0 et la dépréciation de .ix
, je me demande quel est le moyen le plus efficace d’obtenir le même résultat en utilisant les .loc
et .iloc
restants. Je viens de répondre à cette question , mais la deuxième option (ne pas utiliser .ix
) semble inefficace et prolixe.
Fragment:
print df.iloc[df.loc[df['cap'].astype(float) > 35].index, :-1]
Est-ce la bonne façon d'utiliser le filtrage conditionnel et le positionnement d'index?
Vous pouvez rester dans le monde d'une seule loc
en accédant aux valeurs d'index dont vous avez besoin en découpant cet index avec des positions.
df.loc[
df['cap'].astype(float) > 35],
df.columns[:-1]
]
En général, vous préféreriez éviter l'indexation en chaîne dans les pandas (bien que, à proprement parler, vous utilisiez en fait deux méthodes d'indexation différentes). Vous ne pouvez pas modifier votre dataframe de cette manière (détails dans/ docs ), et les documents citent les performances comme une autre raison (indexation une fois ou deux fois).
Pour ces derniers, il est généralement insignifiant (ou plutôt improbable de constituer un goulot d'étranglement dans votre code) et ne semble en réalité pas être le cas (du moins dans l'exemple suivant):
df = pd.DataFrame(np.random.uniform(size=(100000,10)),columns = list('abcdefghij'))
# Get columns number 2:5 where value in 'a' is greater than 0.5
# (i.e. Boolean mask along axis 0, position slice of axis 1)
# Deprecated .ix method
%timeit df.ix[df['a'] > 0.5,2:5]
100 loops, best of 3: 2.14 ms per loop
# Boolean, then position
%timeit df.loc[df['a'] > 0.5,].iloc[:,2:5]
100 loops, best of 3: 2.14 ms per loop
# Position, then Boolean
%timeit df.iloc[:,2:5].loc[df['a'] > 0.5,]
1000 loops, best of 3: 1.75 ms per loop
# .loc
%timeit df.loc[df['a'] > 0.5, df.columns[2:5]]
100 loops, best of 3: 2.64 ms per loop
# .iloc
%timeit df.iloc[np.where(df['a'] > 0.5)[0],2:5]
100 loops, best of 3: 9.91 ms per loop
Conclusion: si vous voulez vraiment éviter .ix
et que vous n’avez pas l’intention de modifier les valeurs de votre cadre de données, optez pour l’indexation chaînée. D'un autre côté (la manière «correcte» mais peut-être plus compliquée), si vous devez modifier des valeurs, faites .iloc
avec np.where()
ou .loc
avec des tranches entières de df.index
ou df.columns
.
Pourquoi ne pas transformer ceci en une indexation en deux étapes:
df[df['cap'].astype(float) > 35].iloc[:,:-1]
ou même:
df[df['cap'].astype(float) > 35].drop('cap',1)