在pandas中将两个Series组合成DataFrame

403

我有两个Series,分别是s1s2,它们的索引相同但不连续。我如何将s1s2组合成一个DataFrame中的两列,并保留其中一个索引作为第三列?

9个回答

578

我认为concat是一个很好的方法。如果它们存在,它将使用Series的名称属性作为列名(否则仅对其进行编号):

In [1]: s1 = pd.Series([1, 2], index=['A', 'B'], name='s1')

In [2]: s2 = pd.Series([3, 4], index=['A', 'B'], name='s2')

In [3]: pd.concat([s1, s2], axis=1)
Out[3]:
   s1  s2
A   1   3
B   2   4

In [4]: pd.concat([s1, s2], axis=1).reset_index()
Out[4]:
  index  s1  s2
0     A   1   3
1     B   2   4

注意:这适用于超过2个系列。


5
与使用字典解决方案相比,这实际上也避免了复制。 - Jeff
在某个实例中,它似乎告诉我“ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()” - 有什么想法吗? - user7289
@Mannaggia 嗯,我认为这取决于你想要什么样的答案... 用合并操作:pd.merge(s1.reset_index(), s2.reset_index(), how='outer') - Andy Hayden
从pandas网站上可以看到,值得注意的是concat(因此也包括append)会对数据进行完全复制,频繁重复使用此函数可能会导致显著的性能损失。如果您需要在多个数据集上使用该操作,请使用列表推导式。 - dafinguzman
3
@dafinguzman,“不断重复使用此函数”的意思是,你应该更喜欢进行一次连接pd.concat([list_of_dataframes])而不是多次连接 new_df = pd.DataFrame(); for df in list_of_dsf: new_df = pd.concat([new_df, df])或者类似的操作。 - Andy Hayden
显示剩余5条评论

77

如果两者具有相同的索引,您可以使用to_frame

>= v0.23

a.to_frame().join(b)

< v0.23

a.to_frame().join(b.to_frame())

13
也许这样更合适:a.to_frame(name='a').join(b.to_frame(name='b'))。 - Ashok K Harnal

38
Pandas会自动对齐这些传入的序列并创建联合索引,这里它们恰好相同。reset_index将索引移动到一列中。
In [2]: s1 = Series(randn(5),index=[1,2,4,5,6])

In [4]: s2 = Series(randn(5),index=[1,2,4,5,6])

In [8]: DataFrame(dict(s1 = s1, s2 = s2)).reset_index()
Out[8]: 
   index        s1        s2
0      1 -0.176143  0.128635
1      2 -1.286470  0.908497
2      4 -0.995881  0.528050
3      5  0.402241  0.458870
4      6  0.380457  0.072251

np.random.randn(5) - shaneb

21

如果我可以回答这个问题。

将系列转换为数据帧的基本原理是要理解:

1. 在概念级别上,数据帧中的每一列都是一个系列。

2. 每个列名都是一个键名称,映射到一个系列。

如果您记住了上述两个概念,就可以想出许多将系列转换为数据帧的方法。 一个简单的解决方法如下:

在此创建两个系列

import pandas as pd

series_1 = pd.Series(list(range(10)))

series_2 = pd.Series(list(range(20,30)))
创建一个只包含所需列名的空数据框。
df = pd.DataFrame(columns = ['Column_name#1', 'Column_name#1'])

使用映射的概念将系列值放入数据框中

df['Column_name#1'] = series_1

df['Column_name#2'] = series_2

现在立即查看结果

df.head(5)

20

示例代码:

a = pd.Series([1,2,3,4], index=[7,2,8,9])
b = pd.Series([5,6,7,8], index=[7,2,8,9])
data = pd.DataFrame({'a': a,'b':b, 'idx_col':a.index})

Pandas允许您使用dict创建一个DataFrame,其中将Series用作值,列名用作键。当它发现值为Series时,它使用Series索引作为DataFrame索引的一部分。这种数据对齐是Pandas的主要优点之一。因此,除非您有其他需求,否则新创建的DataFrame具有重复的值。在上面的示例中,data['idx_col']data.index具有相同的数据。


10

我不确定我完全理解你的问题,但这是你想做的吗?

pd.DataFrame(data=dict(s1=s1, s2=s2), index=s1.index)

(index=s1.index 在这里并不必要)


8

基于join()的解决方案的简化:

df = a.to_frame().join(b)

7

如果您试图连接一系列等长的序列,但它们的索引不匹配(这是常见情况),那么连接它们会在不匹配的地方生成NAs。

x = pd.Series({'a':1,'b':2,})
y = pd.Series({'d':4,'e':5})
pd.concat([x,y],axis=1)

#Output (I've added column names for clarity)
Index   x    y
a      1.0  NaN
b      2.0  NaN
d      NaN  4.0
e      NaN  5.0

假设您不关心索引是否匹配,解决方案是在连接它们之前重新索引两个序列。如果 drop=False(默认值),则 Pandas 会在新数据框的一列中保存旧索引(这里为简单起见删除了索引)。

pd.concat([x.reset_index(drop=True),y.reset_index(drop=True)],axis=1)

#Output (column names added):
Index   x   y
0       1   4
1       2   5

1
我使用pandas将我的numpy数组或iseries转换为dataframe,然后通过键名“prediction”添加附加列。如果需要将dataframe转换回列表,则使用values.tolist()。
output=pd.DataFrame(X_test)
output['prediction']=y_pred

list=output.values.tolist()     

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接