Estoy tratando de inferir una clasificación según el tamaño de una persona en un marco de datos como este:
Size 1 80000 2 8000000 3 8000000000 ...Quiero que se vea así:
Size Classification 1 80000 <1m 2 8000000 1-10m 3 8000000000 >1bi ...Entiendo que el proceso ideal sería aplicar una función lambda como esta:
df['Classification']=df['Size'].apply(lambda x: "<1m" if x<1000000 else "1-10m" if 1000000<x<10000000 else ...)Revisé algunas publicaciones sobre múltiples ifs en una función lambda, aquí hay un enlace de ejemplo , pero ese synthax no funciona para mí por alguna razón en una declaración de múltiples ifs, pero estaba funcionando en una sola condición if.
Así que probé esta solución "muy elegante":
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)Resuelve que "pasar" parece no aplicarse a las funciones lambda también:
df['Classification']=df['Size'].apply(lambda x: "<1m" if x<1000000 else pass) SyntaxError: invalid syntax¿Alguna sugerencia sobre la sintaxis correcta para una declaración if múltiple dentro de una función lambda en un método de aplicación en Pandas? Las soluciones multilínea o de una sola línea funcionan para mí.
Aquí hay un pequeño ejemplo sobre el que puede construir:
Básicamente, lambda x: x.. es la frase breve de una función. Lo que apply realmente pide es una función que usted mismo pueda recrear fácilmente.
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)Devoluciones:
Size Classification 0 80000 <1m 1 8000000 1-10m 2 800000000 N/APuede usar la función pd.cut :
bins = [0, 1000000, 10000000, 50000000, ...] labels = ['<1m','1-10m','10-50m', ...] df['Classification'] = pd.cut(df['Size'], bins=bins, labels=labels)Usando la búsqueda ordenada de searchsorted
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 desea producir una nueva columna en el marco de datos existente
df['Classification'] = labels[bins.searchsorted(df['Size'].values)]alguna explicación
De Documentos: np.searchsorted
Encuentre índices donde se deben insertar elementos para mantener el orden.
Encuentre los índices en una matriz ordenada a tal que, si los elementos correspondientes en v se insertaran antes de los índices, se conservaría el orden de a.
La matriz de labels tiene una longitud mayor que la de los bins en uno. Porque cuando algo es mayor que el valor máximo en bins , searchsorted devuelve un -1 . Cuando cortamos labels , esto toma la última etiqueta.