J'essaie d'inférer une classification en fonction de la taille d'une personne dans une trame de données comme celle-ci:
Size
1 80000
2 8000000
3 8000000000
...
Je veux que ça ressemble à ceci:
Size Classification
1 80000 <1m
2 8000000 1-10m
3 8000000000 >1bi
...
Je comprends que le processus idéal serait d'appliquer une fonction lambda comme celle-ci:
df['Classification']=df['Size'].apply(lambda x: "<1m" if x<1000000 else "1-10m" if 1000000<x<10000000 else ...)
J'ai vérifié quelques articles concernant plusieurs ifs dans une fonction lambda, voici un exemple de lien , mais ce synthax ne fonctionne pas pour moi pour une raison quelconque dans une instruction multiple ifs, mais il fonctionnait dans un seul si condition.
J'ai donc essayé cette solution "très élégante":
df['Classification']=df['Size'].apply(lambda x: "<1m" if x<1000000 else pass)
df['Classification']=df['Size'].apply(lambda x: "1-10m" if 1000000 < x < 10000000 else pass)
df['Classification']=df['Size'].apply(lambda x: "10-50m" if 10000000 < x < 50000000 else pass)
df['Classification']=df['Size'].apply(lambda x: "50-100m" if 50000000 < x < 100000000 else pass)
df['Classification']=df['Size'].apply(lambda x: "100-500m" if 100000000 < x < 500000000 else pass)
df['Classification']=df['Size'].apply(lambda x: "500m-1bi" if 500000000 < x < 1000000000 else pass)
df['Classification']=df['Size'].apply(lambda x: ">1bi" if 1000000000 < x else pass)
Fonctionne que "passer" ne semble pas s'appliquer également aux fonctions lambda:
df['Classification']=df['Size'].apply(lambda x: "<1m" if x<1000000 else pass)
SyntaxError: invalid syntax
Des suggestions sur le synthax correct pour une instruction multiple if à l'intérieur d'une fonction lambda dans une méthode apply dans Pandas? Les solutions multilignes ou monolignes fonctionnent pour moi.
Voici un petit exemple sur lequel vous pouvez vous appuyer:
Fondamentalement, lambda x: x..
est la ligne courte d'une fonction. Ce qui s'applique vraiment, c'est une fonction que vous pouvez facilement recréer.
import pandas as pd
# Recreate the dataframe
data = dict(Size=[80000,8000000,800000000])
df = pd.DataFrame(data)
# Create a function that returns desired values
# You only need to check upper bound as the next Elif-statement will catch the value
def func(x):
if x < 1e6:
return "<1m"
Elif x < 1e7:
return "1-10m"
Elif x < 5e7:
return "10-50m"
else:
return 'N/A'
# Add Elif statements....
df['Classification'] = df['Size'].apply(func)
print(df)
Retour:
Size Classification
0 80000 <1m
1 8000000 1-10m
2 800000000 N/A
Vous pouvez utiliser pd.cut
fonction :
bins = [0, 1000000, 10000000, 50000000, ...]
labels = ['<1m','1-10m','10-50m', ...]
df['Classification'] = pd.cut(df['Size'], bins=bins, labels=labels)
Utilisation de searchsorted
de Numpy
labels = np.array(['<1m', '1-10m', '10-50m', '>50m'])
bins = np.array([1E6, 1E7, 5E7])
# Using assign is my preference as it produces a copy of df with new column
df.assign(Classification=labels[bins.searchsorted(df['Size'].values)])
Si vous vouliez produire une nouvelle colonne dans une trame de données existante
df['Classification'] = labels[bins.searchsorted(df['Size'].values)]
Quelques explications
Trouvez les indices où les éléments doivent être insérés pour maintenir l'ordre.
Trouvez les indices dans un tableau trié tel que, si les éléments correspondants dans v étaient insérés avant les indices, l'ordre de a serait conservé.
Le tableau labels
a une longueur supérieure à celle de bins
d'une unité. Parce que lorsque quelque chose est supérieur à la valeur maximale dans bins
, searchsorted
renvoie un -1
. Lorsque nous coupons labels
, cela prend la dernière étiquette.