Transform each value in a column by applying a formula element-by-element — here, rounding each price to the nearest ten. With pandas, Series.apply calls the function once per element and collects the results.

By hand

Loop over prices, compute scaled for each value via round(p / 10) * 10, and append to result. Each iteration shows both the intermediate scaled value and the growing result list.

naive.py
Replay: real traced execution (multi-file project)
prices = [14, 27, 33, 56]
result = []
for p in prices:
    scaled = round(p / 10) * 10
    result.append(scaled)
print('RESULT:', result)
  1. prices ← [14, 27, 33, 56]

    1prices = [14, 27, 33, 56]2result = []
    values this step[14, 27, 33, 56]prices
  2. result ← []

    1prices = [14, 27, 33, 56]2result = []3for p in prices:
    values this step[]result
  3. p ← 14

    2result = []3for p in prices:4    scaled = round(p / 10) * 10
    values this step14p
  4. scaled ← 10

    3for p in prices:4    scaled = round(p / 10) * 105    result.append(scaled)
    values this step10scaled
  5. result ← [10]

    4    scaled = round(p / 10) * 105    result.append(scaled)6print('RESULT:', result)
    values this step[] [10]result
  6. p ← 27

    2result = []3for p in prices:4    scaled = round(p / 10) * 10
    values this step14 27p
  7. scaled ← 30

    3for p in prices:4    scaled = round(p / 10) * 105    result.append(scaled)
    values this step10 30scaled
  8. result ← [10, 30]

    4    scaled = round(p / 10) * 105    result.append(scaled)6print('RESULT:', result)
    values this step[10] [10, 30]result
  9. p ← 33

    2result = []3for p in prices:4    scaled = round(p / 10) * 10
    values this step27 33p
  10. scaled = round(p / 10) * 10

    3for p in prices:4    scaled = round(p / 10) * 105    result.append(scaled)
  11. result ← [10, 30, 30]

    4    scaled = round(p / 10) * 105    result.append(scaled)6print('RESULT:', result)
    values this step[10, 30] [10, 30, 30]result
  12. p ← 56

    2result = []3for p in prices:4    scaled = round(p / 10) * 10
    values this step33 56p
  13. scaled ← 60

    3for p in prices:4    scaled = round(p / 10) * 105    result.append(scaled)
    values this step30 60scaled
  14. result ← [10, 30, 30, 60]

    4    scaled = round(p / 10) * 105    result.append(scaled)6print('RESULT:', result)
    values this step[10, 30, 30] [10, 30, 30, 60]result
  15. for p in prices:

    2result = []3for p in prices:4    scaled = round(p / 10) * 10
  16. stdout ← RESULT: [10, 30, 30, 60]

    5    result.append(scaled)6print('RESULT:', result)
    values this stepRESULT: [10, 30, 30, 60]stdout

With pandas

df['price'].apply(lambda x: round(x / 10) * 10) returns a new Series with the transformed values. The index and dtype are preserved.

library.py
import pandas as pd
from dalib.display import set_display
set_display()

prices = [14, 27, 33, 56]
df = pd.DataFrame({'price': prices})
result = df['price'].apply(lambda x: round(x / 10) * 10)
print('index:', result.index.tolist())
print('values:', result.tolist())
print('dtype:', result.dtype)
print('RESULT:', result.tolist())
index: [0, 1, 2, 3]
values: [10, 30, 30, 60]
dtype: int64
RESULT: [10, 30, 30, 60]

Implementation notes

  • Series.apply is an elementwise API — it calls the Python function once per element, not as a vectorized kernel. For simple arithmetic, prefer a vectorized expression: df['price'] * 2 is faster than df['price'].apply(lambda x: x * 2) because it avoids per-element Python calls.
  • Use .apply when the transformation cannot be expressed as built-in vectorized operations — e.g. multi-step logic or calls to external functions.
  • Cross-reference: map-transform (python-data-basics) for the pure-Python version; map-values (this chapter) for dict-based remapping via Series.map.