In 2009, I finally decided to get serious about losing some weight. I was near my all-time peak of 290 pounds and feeling terrible. I was also spending my weeks near work several hours from home, and nothing but free time on my hands. Rather than spend it watching tv and eating junk food, I though I’d try to prepare healthy meals and give running a shot.
Over the following year I managed to lose 75 pounds, developed a running habit, including running races up to 15K, and generally learned to appreciate a healthy lifestyle. This isn’t the whole story (lowlight - I gained about half back; highlight: I ran a marathon), but more on that in future posts.
This is about the data! This post and succeeding ones will be about my trying to learn some exploratory data analysis skills using iPython Notebook (what an incredible tool!), pandas, matplotlib, SciPy, and other tools.
During the course of my weight loss from mid-2009 to mid-2010, I weighed myself nearly every day. Additionally, I recorded food and exercise calories most days. Let’s look at the results.
Note: I have some separate scripts that you will see me using here. You can see my code (plus the original iPython Notebook) on GitHub.
import matplotlib.pyplot as plt run weight_analysis.py from weight_utils import *
When you’re losing weight, they tell you to weigh yourself weekly (or less often), because the journey downward can be, well, indirect:
ax = w1y.plot() ax.set_ylabel('Weight (lbs)');
But there are ways to deal with the noise of daily weight fluctuation. A method that I found helpful was that outlined in The Hacker’s Diet. Namely, use a moving average of your weight as your indicator of progress. Since it’s a lagging indicator, if you are losing weight most of your weights measurements will be below average, bringing the average down and giving you more “losing weight” days. I like how Erv Walter demonstrates it graphically here.
ax = w1y.plot(style='b.', alpha=0.2) smooth.plot(style='r') plt.title('Daily Weight Data (Smoothed and Unsmoothed)') ax.set_ylabel('Weight (lbs)');
Well sure, you could do that, but then you’d lose out on all this wonderful data! For instance, don’t you want to know while you feel pretty bloated after a football weekend with your college pals? Well, maybe it’s because you gained ten pounds which you promptly lost with barely a blip in the overall trend.
ax = w1y['09-2009'].plot(title='Daily Weight Data - September 2009') smooth['09-2009'].plot(style='r') ax.set_ylabel('Weight (lbs)');
More on this later, but I found that having daily data gave me real insight into how my body reacts to changes in diet and activity, further helping me to react calmly and thoughtfully to inevitable weight fluctuations. It also gave me an intuitive understanding for why impermanent weight-loss solutions are so impermanent.
##Measuring weight loss rate You can also estimate your short- and long-term weight loss rate. And, as usual, using daily data makes this infinitely more fun! I just calculated the day-to-day weight difference, converted it to a weekly rate, and smoothed it with a 7-day and 90-day window (the former giving me more instantaneous, but noisy, insight - and the latter describing the overall trend).
ax = pd.ewma(smooth.diff()*-7, 90).plot(title='Weight Loss Rate in Pounds per Week', label='90-day window') pd.ewma(smooth.diff()*-7, 7).plot(color='r', label='7-day window') ax.set_ylabel('Weekly Weight Loss (negative numbers are Gains)') ax.legend();
As you can see, I started off losing a lot of weight quickly (pretty common, especially if you’re coming off a period of near-constant fried food and beer). My rate of weight loss steadily declined through August and September, until it settled in at about two pound per week (although September included the aforementioned football weekend blip). At the holidays, my weight loss dropped off to a little over a pound per week (my budget was for 1.5 pounds - I wasn’t perfect), but you can see the individual holidays (Thanksgiving and Christmas/New Years) where I actually gained weight briefly. I still don;t know what happened in early February. Speculation on that later. My weight loss was pretty steady through the spring, then settled in at about a pound per week to finish it off.
##Weight fluctuation patterns One pretty predictable element of my weight loss fluctuations was the weekly pattern I observed along the way. Since for the most part, my weight loss efforts were more focused during the week, a pretty consistent pattern emerged. I would typically see dramatic weight loss Wednesday through Saturday followed by dramatic weight gains Sunday through Tuesday. Once I understood these patterns I could shrug off the upticks early in the week and look forward to the plummeting measurements at the end, always feeling pretty good going into the weekend.
daily_pattern = np.concatenate((np.zeros(1), np.array(avg_dds['Padded']))).cumsum() fig, ax = plt.subplots(1) ax.plot(daily_pattern) locs, labels = xticks() xticks(np.arange(8), ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')) ax.set_ylabel('Average weight gain (loss) from prior day') plt.show()
So, that’s the weight data itself (the outcome). But, what about the inputs that drove this weight loss - calories in and calories out? That’s the next post in this series.