Pandas DataFrame insert / fill missing rows from previous dates
<p>I have a <code>DataFrame</code> consisting of <code>date</code>s, other columns and a numerical value, where some value combinations in "other columns" could be missing, and I want to populate them from previous <code>date</code>s.</p>

<p>Example. Say the <code>DataFrame</code> is like below. You can see on <code>2016-01-01</code>, we have data for <code>(LN, A)</code>, <code>(LN, B)</code>, <code>(NY, A)</code> and <code>(NY, B)</code> on columns <code>(location, band)</code>.</p>

<pre>
        date  location  band  value
0 2016-01-01        LN     A   10.0
1 2016-01-01        LN     B    5.0
2 2016-01-01        NY     A    9.0
3 2016-01-01        NY     B    6.0
4 2016-01-02        LN     A   11.0
5 2016-01-02        NY     B    7.0
6 2016-01-03        NY     A   10.0
</pre>

<p>Then you notice on <code>2016-01-02</code>, we only have <code>(LN, A)</code> and <code>(NY, B)</code>, but <code>(LN, B)</code> and <code>(NY, A)</code> are missing. Again, on <code>2016-01-03</code>, only <code>(NY, A)</code> is available; all other three combinations are missing.</p>

<p>What I want to do is to populate the missing combinations of each date from its predecessor. Say for <code>2016-01-02</code>, I would like to add two more rows, "rolled over" from <code>2016-01-01</code>: <code>(LN, B, 5.0)</code> and <code>(NY, A, 9.0)</code> for columns <code>(location, band, value)</code>. Same for <code>2016-01-03</code>. So as to make the whole thing like below:</p>

<pre>
        date  location  band  value
 0 2016-01-01        LN     A   10.0
 1 2016-01-01        LN     B    5.0
 2 2016-01-01        NY     A    9.0
 3 2016-01-01        NY     B    6.0
 4 2016-01-02        LN     A   11.0
 5 2016-01-02        NY     B    7.0
 6 2016-01-03        NY     A   10.0
 7 2016-01-02        LN     B    5.0
 8 2016-01-02        NY     A    9.0
 9 2016-01-03        LN     A   11.0
10 2016-01-03        LN     B    5.0
11 2016-01-03        NY     B    7.0
</pre>

<p>Note rows 7-11 are populated from rows 1, 2, 4, 7 and 5, respectively. The order is not really important as I can always sort afterwards if all the data I need is present.</p>

<p>Anyone to help? Thanks a lot!</p>

<p>You can use a <code>unstack</code>/<code>stack</code> method to get all missing values, followed by a forward fill:</p>

<pre><code># Use unstack/stack to add missing locations.
df = df.set_index(['date', 'location', 'band']) \
       .unstack(level=['location', 'band']) \
       .stack(level=['location', 'band'], dropna=False)

# Forward fill NaN values within ['location', 'band'] groups.
df = df.groupby(level=['location', 'band']).ffill().reset_index()
</code></pre>

<p>Or you can directly build a <code>MultiIndex</code> containing all combinations:</p>

<pre><code># Build the full MultiIndex, set the partial MultiIndex, and reindex.
levels = ['date', 'location', 'band']
full_idx = pd.MultiIndex.from_product([df[col].unique() for col in levels], names=levels)
df = df.set_index(levels).reindex(full_idx)

# Forward fill NaN values within ['location', 'band'] groups.
df = df.groupby(level=['location', 'band']).ffill().reset_index()
</code></pre>

<p>The resulting output for either method:</p>

<pre><code>         date location band  value
0  2016-01-01       LN    A   10.0
1  2016-01-01       LN    B    5.0
2  2016-01-01       NY    A    9.0
3  2016-01-01       NY    B    6.0
4  2016-01-02       LN    A   11.0
5  2016-01-02       LN    B    5.0
6  2016-01-02       NY    A    9.0
7  2016-01-02       NY    B    7.0
8  2016-01-03       LN    A   11.0
9  2016-01-03       LN    B    5.0
10 2016-01-03       NY    A   10.0
11 2016-01-03       NY    B    7.0
</code></pre>

python pandas dataframe