Pandas:从Series创建DataFrame
我现在的代码如下 - 我正在导入一个MAT文件,并试图从里面的变量创建一个数据框(DataFrame):
mat = loadmat(file_path) # load mat-file
Variables = mat.keys() # identify variable names
df = pd.DataFrame # Initialise DataFrame
for name in Variables:
B = mat[name]
s = pd.Series (B[:,1])
在循环中,我可以为每个变量创建一个序列(这些变量是有两列的数组 - 所以我需要的值在第二列)。
我想问的是,怎么把这些序列添加到数据框里?我查阅了文档,但里面的例子似乎都不太适合我想做的事情。
4 个回答
我想另一种可能更快的方法来实现这个目标是:
1) 使用字典推导式来获取想要的字典(也就是提取每个数组的第二列)。
2) 然后使用 pd.DataFrame
直接从这个字典创建一个实例,而不需要逐列循环和拼接。
假设你的 mat
看起来像这样(你可以忽略这一部分,因为你的 mat
是从文件中加载的):
In [135]: mat = {'a': np.random.randint(5, size=(4,2)),
.....: 'b': np.random.randint(5, size=(4,2))}
In [136]: mat
Out[136]:
{'a': array([[2, 0],
[3, 4],
[0, 1],
[4, 2]]), 'b': array([[1, 0],
[1, 1],
[1, 0],
[2, 1]])}
然后你可以这样做:
In [137]: df = pd.DataFrame ({name:mat[name][:,1] for name in mat})
In [138]: df
Out[138]:
a b
0 0 0
1 4 1
2 1 0
3 2 1
[4 rows x 2 columns]
现在有一个叫做 pandas.Series.to_frame
的方法:
Series.to_frame(name=NoDefault.no_default)
这个方法可以把一个序列(Series)转换成一个数据框(DataFrame)。
参数说明
nameobject
,可选:你可以传入一个名字,这个名字会替代序列的名字(如果它有名字的话)。返回值
DataFrame
:返回一个数据框,表示这个序列的内容。示例
s = pd.Series(["a", "b", "c"], name="vals") s.to_frame()
其实不需要先初始化一个空的DataFrame(你甚至没有这样做,你需要用pd.DataFrame()
加上括号)。
相反,如果你想创建一个DataFrame,每一列是一个Series,
- 首先,准备一个Series的列表,叫做
series
,然后 - 用
df = pd.concat(series, axis=1)
把它们横向合并起来。
大概是这样的:
series = [pd.Series(mat[name][:, 1]) for name in Variables]
df = pd.concat(series, axis=1)
下面是如何创建一个数据框(DataFrame),让每个系列(Series)成为一行。
如果只有一个系列(结果就是一个单行的数据框):
series = pd.Series([1,2], index=['a','b'])
df = pd.DataFrame([series])
如果有多个系列,且它们的索引是一样的:
cols = ['a','b']
list_of_series = [pd.Series([1,2],index=cols), pd.Series([3,4],index=cols)]
df = pd.DataFrame(list_of_series, columns=cols)
如果有多个系列,且它们的索引可能不同:
list_of_series = [pd.Series([1,2],index=['a','b']), pd.Series([3,4],index=['a','c'])]
df = pd.concat(list_of_series, axis=1).transpose()
如果想创建一个数据框,让每个系列成为一列,可以看看其他人的回答。或者,你也可以像上面那样先创建一个每个系列为一行的数据框,然后使用 df.transpose()
。不过,后者的方法在列的数据类型不一样时效率会比较低。