Pandas Dataframe或Panel to 3d numpy array

时间:2014-05-05 17:33:15

标签: python numpy pandas

设定:

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。如果没有本地方式,那么从数十万行和数百列迭代构建数组的最佳方法是什么?

3 个答案:

答案 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)。