Pandas 多索引 DataFrame 到 Numpy Ndarray
Posted
技术标签:
【中文标题】Pandas 多索引 DataFrame 到 Numpy Ndarray【英文标题】:Pandas Multi-Index DataFrame to Numpy Ndarray 【发布时间】:2018-02-15 04:05:22 【问题描述】:我正在尝试将多索引 pandas DataFrame
转换为 numpy.ndarray
。数据框如下:
s1 s2 s3 s4
Action State
1 s1 0.0 0 0.8 0.2
s2 0.1 0 0.9 0.0
2 s1 0.0 0 0.9 0.1
s2 0.0 0 1.0 0.0
我希望得到的numpy.ndarray
与np.shape() = (2,2,4)
如下:
[[[ 0.0 0.0 0.8 0.2 ]
[ 0.1 0.0 0.9 0.0 ]]
[[ 0.0 0.0 0.9 0.1 ]
[ 0.0 0.0 1.0 0.0]]]
我已经尝试过df.as_matrix()
但这会返回:
[[ 0. 0. 0.8 0.2]
[ 0.1 0. 0.9 0. ]
[ 0. 0. 0.9 0.1]
[ 0. 0. 1. 0. ]]
如何返回第一级的列表列表,每个列表代表一个Action
记录。
【问题讨论】:
之后再整形? 结果中的形状类似于 (2, 2, 4)。 【参考方案1】:一种方式
In [151]: df.groupby(level=0).apply(lambda x: x.values.tolist()).values
Out[151]:
array([[[0.0, 0.0, 0.8, 0.2],
[0.1, 0.0, 0.9, 0.0]],
[[0.0, 0.0, 0.9, 0.1],
[0.0, 0.0, 1.0, 0.0]]], dtype=object)
【讨论】:
不幸的是,这个数组的尺寸与预期数组的尺寸不同:np.shape()
of your result 给出了(2,)
,而预期的np.shape()
是(2,3,3)
【参考方案2】:
您可以使用以下内容:
dim = len(df.index.get_level_values(0).unique())
result = df.values.reshape((dim1, dim1, df.shape[1]))
print(result)
[[[ 0. 0. 0.8 0.2]
[ 0.1 0. 0.9 0. ]]
[[ 0. 0. 0.9 0.1]
[ 0. 0. 1. 0. ]]]
第一行只是查找要分组的组数。
为什么需要这个(或 groupby):一旦你使用 .values
,你就会失去来自 pandas 的 MultiIndex 的维度。所以你需要以某种方式将该维度重新传递给 NumPy。
【讨论】:
请注意,您现在需要使用.to_numpy
而不是 .values
,并且此方法假定您的数据框中存在所有 Action * State * State 组合。【参考方案3】:
使用 Divakar 的建议,np.reshape()
工作:
>>> print(P)
s1 s2 s3 s4
Action State
1 s1 0.0 0 0.8 0.2
s2 0.1 0 0.9 0.0
2 s1 0.0 0 0.9 0.1
s2 0.0 0 1.0 0.0
>>> np.reshape(P,(2,2,-1))
[[[ 0. 0. 0.8 0.2]
[ 0.1 0. 0.9 0. ]]
[[ 0. 0. 0.9 0.1]
[ 0. 0. 1. 0. ]]]
>>> np.shape(P)
(2, 2, 4)
【讨论】:
认为你想要一个更通用的解决方案......不管怎样!【参考方案4】:详细说明 Brad Solomon's answer,以获得更通用的解决方案 - 不同大小的索引和不固定数量的索引 - 可以执行以下操作:
def df_to_numpy(df):
try:
shape = [len(level) for level in df.index.levels]
except AttributeError:
shape = [len(df.index)]
ncol = df.shape[-1]
if ncol > 1:
shape.append(ncol)
return df.to_numpy().reshape(shape)
如果df
缺少子索引reshape
将不起作用。添加它们的一种方法是(也许有更好的解决方案):
def enforce_df_shape(df):
try:
ind = pd.MultiIndex.from_product([level.values for level in df.index.levels])
except AttributeError:
return df
fulldf = pd.DataFrame(-1, columns=df.columns, index=ind) # remove -1 to fill fulldf with nan
fulldf.update(df)
return fulldf
【讨论】:
以上是关于Pandas 多索引 DataFrame 到 Numpy Ndarray的主要内容,如果未能解决你的问题,请参考以下文章
如何在 pandas DataFrame 中恢复\展开多索引
绘制 pandas 多索引 DataFrame,其中一个索引作为 Y 轴,另一个作为 X 轴