How to merge a Series and DataFrame

Update
From v0.24.0 onwards, you can merge on DataFrame and Series as long as the Series is named.

df.merge(s.rename('new'), left_index=True, right_index=True)
# If series is already named,
# df.merge(s, left_index=True, right_index=True)

Nowadays, you can simply convert the Series to a DataFrame with to_frame(). So (if joining on index):

df.merge(s.to_frame(), left_index=True, right_index=True)

Here's one way:

df.join(pd.DataFrame(s).T).fillna(method='ffill')

To break down what happens here...

pd.DataFrame(s).T creates a one-row DataFrame from s which looks like this:

   s1  s2
0   5   6

Next, join concatenates this new frame with df:

   a  b  s1  s2
0  1  3   5   6
1  2  4 NaN NaN

Lastly, the NaN values at index 1 are filled with the previous values in the column using fillna with the forward-fill (ffill) argument:

   a  b  s1  s2
0  1  3   5   6
1  2  4   5   6

To avoid using fillna, it's possible to use pd.concat to repeat the rows of the DataFrame constructed from s. In this case, the general solution is:

df.join(pd.concat([pd.DataFrame(s).T] * len(df), ignore_index=True))

Here's another solution to address the indexing challenge posed in the edited question:

df.join(pd.DataFrame(s.repeat(len(df)).values.reshape((len(df), -1), order='F'), 
        columns=s.index, 
        index=df.index))

s is transformed into a DataFrame by repeating the values and reshaping (specifying 'Fortran' order), and also passing in the appropriate column names and index. This new DataFrame is then joined to df.


You could construct a dataframe from the series and then merge with the dataframe. So you specify the data as the values but multiply them by the length, set the columns to the index and set params for left_index and right_index to True:

In [27]:

df.merge(pd.DataFrame(data = [s.values] * len(s), columns = s.index), left_index=True, right_index=True)
Out[27]:
   a  b  s1  s2
0  1  3   5   6
1  2  4   5   6

EDIT for the situation where you want the index of your constructed df from the series to use the index of the df then you can do the following:

df.merge(pd.DataFrame(data = [s.values] * len(df), columns = s.index, index=df.index), left_index=True, right_index=True)

This assumes that the indices match the length.