Nivel 1 · Calcula el ingreso por línea
¿Es nuevo para ti? Lee primero el concepto: Dividir, aplicar, combinar
0 de 3
La solicitud

De Laura Bennett, Directora de Finanzas
Tu objetivo
Añade a order_items una columna line_revenue = quantity * unit_price * (1 - discount_pct / 100), redondeada a 2 decimales. Asigna a result las primeras 20 filas de esa tabla: todas las columnas originales más line_revenue como última columna, en el orden de filas original.
- Usa el DataFrame
order_itemspendiente - Muestra exactamente
order_item_idorder_idproduct_idquantityunit_pricediscount_pctline_revenuependiente - 20 filas, ordenadas como se pidependiente
Tu código
Cargando el editor…
Solución de referencia
| order_item_id | order_id | product_id | quantity | unit_price |
|---|---|---|---|---|
| 1 | 1001 | 121 | 9 | 31.99 |
| 2 | 1001 | 154 | 3 | 11.99 |
| 3 | 1002 | 154 | 4 | 11.99 |
| 4 | 1002 | 194 | 1 | 149.00 |
Mote revisa tu resultado
Presiona Ejecutar. Cada fila que cumple el objetivo se vuelve una luciérnaga en tu linterna.
Lo que recibe Laura, y por qué
DataFrames
Cargados como DataFrames de pandas, junto con pd y np.
order_items30,338 filas · 6 columnas
order_item_idintegerorder_idintegerproduct_idintegerquantityintegerunit_pricedecimaldiscount_pctdecimal
| order_item_id | order_id | product_id | quantity | unit_price | discount_pct |
|---|---|---|---|---|---|
| 1 | 1001 | 121 | 9 | 31.99 | 0.00 |
| 2 | 1001 | 154 | 3 | 11.99 | 0.00 |
| 3 | 1002 | 154 | 4 | 11.99 | 0.00 |
| 4 | 1002 | 194 | 1 | 149.00 | 0.00 |
| 5 | 1002 | 193 | 2 | 19.99 | 0.00 |
customers2,018 filas · 9 columnas
customer_idintegerfirst_namevarcharlast_namevarcharemailvarcharcityvarcharstatevarcharsignup_datedatesegmentvarcharreferral_sourcevarchar
| customer_id | first_name | last_name | city | state | signup_date | segment | referral_source | |
|---|---|---|---|---|---|---|---|---|
| 1 | Owen | Hudson | owen.hudson@icloud.com | San Francisco | CA | 2022-06-02 | consumer | search |
| 2 | Douglas | Mendoza | dmendoza69@gmail.com | Atlanta | GA | 2022-06-02 | consumer | NaN |
| 3 | Henry | Brooks | hbrooks@lakesidecafe.com | Los Angeles | CA | 2022-06-04 | business | NaN |
| 4 | Brian | Graham | bgraham@bluecedarhomes.com | Seattle | WA | 2022-06-06 | business | |
| 5 | Kyle | Jimenez | kjimenez27@yahoo.com | Indianapolis | IN | 2022-06-07 | consumer | NaN |
products120 filas · 8 columnas
product_idintegernamevarcharcategoryvarcharsubcategoryvarcharunit_pricedecimalunit_costdecimallaunched_ondateis_activeboolean
| product_id | name | category | subcategory | unit_price | unit_cost | launched_on | is_active |
|---|---|---|---|---|---|---|---|
| 101 | Vale Velvet Loveseat | Furniture | Sofas | 1659.00 | NaN | 2023-09-11 | true |
| 102 | Alder Oak Coffee Table | Furniture | Tables | 919.00 | 503.50 | 2024-05-16 | true |
| 103 | Orchard Rattan Dining Chair | Furniture | Chairs | 789.00 | 429.87 | 2023-05-27 | true |
| 104 | Upland Oak Bookcase | Furniture | Storage | 429.00 | 214.70 | 2022-12-20 | true |
| 105 | Avery Leather Bed Frame | Furniture | Beds | 449.00 | 232.70 | 2021-08-31 | true |
orders12,000 filas · 7 columnas
order_idintegercustomer_idintegerorder_datetimestampstatusvarcharchannelvarcharshipping_feedecimalcoupon_codevarchar
| order_id | customer_id | order_date | status | channel | shipping_fee | coupon_code |
|---|---|---|---|---|---|---|
| 1001 | 125 | 2023-01-01 20:51:19 | completed | web | 0.00 | NaN |
| 1002 | 156 | 2023-01-02 07:58:46 | completed | web | 0.00 | NaN |
| 1003 | 22 | 2023-01-02 10:25:27 | completed | marketplace | 4.99 | WELCOME10 |
| 1004 | 48 | 2023-01-02 11:21:51 | completed | marketplace | 4.99 | WELCOME10 |
| 1005 | 82 | 2023-01-02 11:43:36 | completed | web | 0.00 | WELCOME10 |
returns1,673 filas · 5 columnas
return_idintegerorder_item_idintegerreturned_ondatereasonvarcharrefund_amountdecimal
| return_id | order_item_id | returned_on | reason | refund_amount |
|---|---|---|---|---|
| 1 | 14 | 2023-01-10 | damaged | 83.69 |
| 2 | 42 | 2023-01-10 | wrong_item | 19.99 |
| 3 | 105 | 2023-01-14 | wrong_item | 10.99 |
| 4 | 24 | 2023-01-16 | changed_mind | 26.99 |
| 5 | 126 | 2023-01-16 | late | 20.99 |
employees60 filas · 8 columnas
employee_idintegerfirst_namevarcharlast_namevarchardepartmentvarchartitlevarcharmanager_idintegerhire_datedatesalaryinteger
| employee_id | first_name | last_name | department | title | manager_id | hire_date | salary |
|---|---|---|---|---|---|---|---|
| 1 | Catherine | Hale | Executive | Chief Executive Officer | NaN | 2016-03-01 | 285000 |
| 2 | Robert | Kim | Executive | Chief Operating Officer | 1 | 2017-01-09 | 235000 |
| 3 | Megan | Collins | Sales | Head of Sales | 1 | 2018-04-16 | 172000 |
| 4 | Chloe | Gutierrez | Sales | Account Executive | 3 | 2020-01-21 | 72000 |
| 5 | Frank | Bell | Sales | Account Executive | 3 | 2023-05-21 | 73000 |
web_sessions40,000 filas · 7 columnas
session_idintegercustomer_idintegerstarted_attimestampdevicevarcharsourcevarcharpages_viewedintegerconvertedboolean
| session_id | customer_id | started_at | device | source | pages_viewed | converted |
|---|---|---|---|---|---|---|
| 1 | NaN | 2023-01-01 23:02:24 | mobile | paid | 1 | false |
| 2 | 18 | 2023-01-01 15:07:49 | desktop | paid | 1 | false |
| 3 | NaN | 2023-01-01 16:55:46 | desktop | direct | 7 | false |
| 4 | NaN | 2023-01-01 12:43:28 | mobile | organic | 3 | false |
| 5 | NaN | 2023-01-01 13:06:21 | mobile | social | 2 | false |
marketing_spend3,276 filas · 3 columnas
spend_datedatechannelvarcharamountdecimal
| spend_date | channel | amount |
|---|---|---|
| 2023-01-01 | paid | 492.99 |
| 2023-01-01 | 37.38 | |
| 2023-01-01 | social | 200.53 |
| 2023-01-02 | paid | 709.13 |
| 2023-01-02 | 64.13 |
La lección
Aritmética con columnas enteras
Cuando multiplicas dos columnas, pandas las multiplica fila a fila y devuelve una Series nueva:
order_items["quantity"] * order_items["unit_price"]
No hace falta ningún bucle. Esto se llama aritmética vectorizada, y es a la vez más corta y mucho más
rápida que hacer un bucle en Python. Puedes mezclar columnas y números simples libremente:
order_items["unit_price"] * 1.08 aplica el mismo número a cada fila.
Conoce tus unidades
Mira discount_pct antes de usarla:
order_items["discount_pct"].value_counts()
# 0.0, 10.0, 15.0, 20.0, 25.0
Está guardada en puntos porcentuales: 10.0 significa 10% de descuento. Así que la parte que paga el
cliente es 1 - discount_pct / 100. Si escribieras 1 - discount_pct, un descuento del 10% dejaría los
ingresos en negativo. Otros conjuntos de datos guardan la misma idea como fracción (0.10); comprueba
siempre unos cuantos valores.
El ingreso por línea es, por tanto:
order_items["quantity"] * order_items["unit_price"] * (1 - order_items["discount_pct"] / 100)
Dos formas de añadir la columna
La forma directa asigna a un nombre de columna nuevo, lo que modifica el DataFrame en el sitio:
items = order_items.copy()
items["line_revenue"] = (
items["quantity"] * items["unit_price"] * (1 - items["discount_pct"] / 100)
).round(2)
assign devuelve un DataFrame nuevo con la columna añadida y deja el original en paz:
items = order_items.assign(
line_revenue=(
order_items["quantity"] * order_items["unit_price"]
* (1 - order_items["discount_pct"] / 100)
).round(2)
)
assign encaja muy bien en las cadenas de métodos. Dentro de una cadena, donde el DataFrame intermedio no
tiene nombre, pasa una función que lo reciba:
order_items.assign(gross=lambda d: d["quantity"] * d["unit_price"])
Ambos estilos son comunes. Lo importante es evitar la asignación encadenada, como
order_items[order_items["quantity"] > 0]["line_revenue"] = .... Eso escribe en una copia temporal, no en
order_items. Para cambiar solo algunas filas, usa una única llamada a .loc:
items.loc[items["quantity"] <= 0, "line_revenue"] = 0.
Redondeo
.round(2) sobre una Series redondea cada valor. Con dinero, redondea la columna que informas, y ten en
cuenta que la suma de líneas redondeadas puede diferir en un centavo o dos de la suma redondeada de líneas
sin redondear. Los equipos de finanzas suelen definir cuál es la oficial; en caso de duda, pregunta.
Otros patrones de columna nueva
orders["has_coupon"] = orders["coupon_code"].notna() # boolean flag
orders["order_year"] = orders["order_date"].dt.year # part of a date
products["margin"] = products["unit_price"] - products["unit_cost"] # NaN where cost is missing
La aritmética con un valor que falta da un valor que falta, así que margin es NaN para los nueve
productos sin costo. Eso es correcto: no conoces su margen.
Errores comunes
- Tratar
discount_pctcomo una fracción. - Usar
products.unit_price(el precio de lista de hoy) en lugar delunit_pricede la línea (el precio realmente pagado). Los precios subieron en algunos productos en marzo de 2025, así que los dos difieren en las líneas más antiguas. - Esperar que
order_items.assign(...)cambieorder_itemssin guardar el resultado.
¡Linterna encendida!
Practicaste: new columnassignvectorised arithmeticround
- Resuelto
- Sin pistas
- Al primer intento
