设定:
pdf = pd.DataFrame(np.random.rand(4,5), columns = list('abcde'))
pdf['a'][2:]=pdf['a'][0]
pdf['a'][:2]=pdf['a'][1]
pdf.set_index(['a','b'])
输出:
c d e
a b
0.439502 0.115087 0.832546 0.760513 0.776555
0.609107 0.247642 0.031650 0.727773
0.995370 0.299640 0.053523 0.565753 0.857235
0.392132 0.832560 0.774653 0.213692
每个数据系列按索引ID a
分组,b
代表a
其他功能的时间索引。有没有办法让大熊猫产生反映a
分组的numpy 3d数组?目前,它将数据读取为二维,因此pdf.shape
输出(4, 5)
。我想要的是数组是变量形式:
array([[[-1.38655912, -0.90145951, -0.95106951, 0.76570984],
[-0.21004144, -2.66498267, -0.29255182, 1.43411576],
[-0.21004144, -2.66498267, -0.29255182, 1.43411576]],
[[ 0.0768149 , -0.7566995 , -2.57770951, 0.70834656],
[-0.99097395, -0.81592084, -1.21075386, 0.12361382]]])
是否有本地Pandas方法可以做到这一点?请注意,实际数据中每a
个分组的行数是可变的,因此我不能只转置或重塑pdf.values
。如果没有本地方式,那么从数十万行和数百列迭代构建数组的最佳方法是什么?
答案 0 :(得分:7)
我遇到了一个非常相似的问题,并解决了这个问题:
a3d = np.array(list(pdf.groupby('a').apply(pd.DataFrame.as_matrix)))
输出:
array([[[ 0.47780308, 0.93422319, 0.00526572, 0.41645868, 0.82089215],
[ 0.47780308, 0.15372096, 0.20948369, 0.76354447, 0.27743855]],
[[ 0.75146799, 0.39133973, 0.25182206, 0.78088926, 0.30276705],
[ 0.75146799, 0.42182369, 0.01166461, 0.00936464, 0.53208731]]])
验证它是3d,a3d.shape给出(2,2,5)。
最后,要使新创建的维度成为最后一个维度(而不是第一个维度),请使用:
a3d = np.dstack(list(pdf.groupby('a').apply(pd.DataFrame.as_matrix)))
具有(2,5,2)
的形状答案 1 :(得分:1)
panel.values
将直接返回一个numpy数组。这将是最高可接受的dtype,因为所有东西都被压成了一个3-d numpy数组。它将是 new 数组,而不是pandas数据的视图(无论dtype)。
答案 2 :(得分:0)
as_matrix
已过时,这里我们假设第一个键为a
,则a
中的组的长度可能不同,此方法解决了所有问题。
def make_cube(df: pd.DataFrame, idx_cols: List[str]) -> np.ndarray:
"""Make an array cube from a Dataframe
Args:
df: Dataframe
idx_cols: columns defining the dimensions of the cube
Returns:
multi-dimensional array
"""
assert len(set(idx_cols) & set(df.columns)) == len(idx_cols), 'idx_cols must be subset of columns'
df = df.set_index(keys=idx_cols) # don't overwrite a parameter, thus copy!
idx_dims = [len(level) + 1 for level in df.index.levels]
idx_dims.append(len(df.columns))
cube = np.empty(idx_dims)
cube.fill(np.nan)
cube[tuple(np.array(df.index.to_list()).T)] = df.values
return cube
测试:
pdf = pd.DataFrame(np.random.rand(4,5), columns = list('abcde'))
pdf['a'][2:]=pdf['a'][0]
pdf['a'][:2]=pdf['a'][1]
# a, b must be integer
pdf1 = (pdf.assign(a=lambda df: df.groupby(['a']).ngroup())
.assign(b=lambda df: df.groupby(['a'])['b'].cumcount())
)
make_cube(pdf1, ['a', 'b']).shape
给予:(2,2,3)
pdf = pd.DataFrame(np.random.rand(5,5), columns = list('abcde'))
pdf['a'][2:]=pdf['a'][0]
pdf['a'][:2]=pdf['a'][1]
pdf1 = (pdf.assign(a=lambda df: df.groupby(['a']).ngroup())
.assign(b=lambda df: df.groupby(['a'])['b'].cumcount())
)
make_cube(pdf1, ['a', 'b']).shape
给s(2,3,3)。