如何合并Series和DataFrame

Nat*_*oyd 65 python dataframe pandas

如果您来到这里寻找有关如何合并索引DataFrameSeries索引的信息,请查看此答案.

OP的初衷是询问如何将系列元素作为列分配给另一个DataFrame.如果您有兴趣知道答案,请查看EdChum 接受的答案.


我能想到的最好的是

df = pd.DataFrame({'a':[1, 2], 'b':[3, 4]})  # see EDIT below
s = pd.Series({'s1':5, 's2':6})

for name in s.index:
    df[name] = s[name]

   a  b  s1  s2
0  1  3   5   6
1  2  4   5   6
Run Code Online (Sandbox Code Playgroud)

任何人都可以建议更好的语法/更快的方法?

我的尝试:

df.merge(s)
AttributeError: 'Series' object has no attribute 'columns'
Run Code Online (Sandbox Code Playgroud)

df.join(s)
ValueError: Other Series must have a name
Run Code Online (Sandbox Code Playgroud)

编辑前两个答案突出显示了我的问题的问题,所以请使用以下内容来构建df:

df = pd.DataFrame({'a':[np.nan, 2, 3], 'b':[4, 5, 6]}, index=[3, 5, 6])
Run Code Online (Sandbox Code Playgroud)

最后的结果

    a  b  s1  s2
3 NaN  4   5   6
5   2  5   5   6
6   3  6   5   6
Run Code Online (Sandbox Code Playgroud)

Nic*_*ley 135

更新
从v0.24.0开始,只要系列命名,就可以合并DataFrame和Series.

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)
Run Code Online (Sandbox Code Playgroud)

如今,您只需使用to_frame()将Series转换为DataFrame 即可.所以(如果加入索引):

df.merge(s.to_frame(), left_index=True, right_index=True)
Run Code Online (Sandbox Code Playgroud)

  • 使用问题的`df`和`s`的定义,这个答案为我返回一个空的数据帧,*不是*在问题中请求的结果.我们不想匹配索引; 我们想将`s`值广播到`df`的所有行. (4认同)
  • 这是在解决一个不同的问题:“给定一个 DataFrame 和 Series,如何将它们合并到索引上”。OP 的问题是“将 Series 的每个元素分配为 DataFrame 中的一个新列”。 (2认同)

EdC*_*ica 20

您可以从系列中构造一个数据框,然后与数据框合并.因此,您将数据指定为值,但将它们乘以长度,将列设置为索引,并将left_index和right_index的参数设置为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
Run Code Online (Sandbox Code Playgroud)

编辑你希望系列中构造的df的索引使用df索引然后你可以执行以下操作的情况:

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

这假设索引与长度匹配.


Ale*_*ley 6

这是一种方法:

df.join(pd.DataFrame(s).T).fillna(method='ffill')
Run Code Online (Sandbox Code Playgroud)

分解这里发生的事情......

pd.DataFrame(s).T创建一个单行的 DataFrame,s它看起来像这样:

   s1  s2
0   5   6
Run Code Online (Sandbox Code Playgroud)

接下来,join将这个新框架与df

   a  b  s1  s2
0  1  3   5   6
1  2  4 NaN NaN
Run Code Online (Sandbox Code Playgroud)

最后,NaN使用fillnaforward-fill ( ffill) 参数将索引 1 处的值填充为列中的先前值:

   a  b  s1  s2
0  1  3   5   6
1  2  4   5   6
Run Code Online (Sandbox Code Playgroud)

为了避免使用fillna,可以使用pd.concat重复从 构造的 DataFrame 的行s。在这种情况下,一般的解决方案是:

df.join(pd.concat([pd.DataFrame(s).T] * len(df), ignore_index=True))
Run Code Online (Sandbox Code Playgroud)

这是解决已编辑问题中提出的索引挑战的另一种解决方案:

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

s通过重复值和重塑(指定“Fortran”顺序),并传入适当的列名和索引,将其转换为 DataFrame。然后将这个新的 DataFrame 加入到df.