如何在python中绘制3D数据的核密度估计(KDE)和零交叉?

如何在python中绘制3D数据的核密度估计(KDE)和零交叉?,python,python-2.7,numpy,pandas,plot,Python,Python 2.7,Numpy,Pandas,Plot,我有三维数据集(X,Y,Z)。我想执行KDE,绘制数据及其估计。然后,得到零交叉点并用KDE绘制它。我的尝试如下。我有以下问题: 行X,Y=np.mgrid[xmin:xmax:100j,ymin:ymax:100j]和positions=np.vstack([X.ravel(),Y.ravel(),Z.ravel()])as(kde文档)它们在可视化原始数据的真实估计时会有任何影响吗?。我真的不明白为什么我必须使用最小值和最大值来执行KDE,然后使用ravel() 为什么我必须在f=np.re

我有三维数据集(X,Y,Z)。我想执行KDE,绘制数据及其估计。然后,得到零交叉点并用KDE绘制它。我的尝试如下。我有以下问题:

  • X,Y=np.mgrid[xmin:xmax:100j,ymin:ymax:100j]
    positions=np.vstack([X.ravel(),Y.ravel(),Z.ravel()])
    as(kde文档)它们在可视化原始数据的真实估计时会有任何影响吗?。我真的不明白为什么我必须使用最小值和最大值来执行KDE,然后使用
    ravel()
  • 为什么我必须在
    f=np.reformate(kernel(positions).T,X.shape)

  • 代码正确吗

  • 我未能用KDE估计和KDE估计/零交叉原始数据绘制原始数据:

  • 零交点应该是向量吗?。在下面的代码中,它是元组

    df = pd.read_csv(file, delimiter = ',')
    Convert series from data-frame into arrays
    X = np.array(df['x']) 
    Y = np.array(df['y']) 
    Z = np.array(df['z'])
    data = np.vstack([X, Y, Z])
    # perform KDE
    kernel = scipy.stats.kde.gaussian_kde(data)
    density = kernel(data)
    fig, ax = plt.subplots(subplot_kw=dict(projection='3d'))
    x, y, z = data
    scatter = ax.scatter(x, y, z, c=density)
    xmin = values[0].min()
    xmax = values[0].max()
    ymin = values[1].min()
    ymax = values[1].max()
    zmin = values[2].min()
    zmax = values[2].max()
    X,Y, Z =      np.mgrid[xmin:xmax:100j,ymin:ymax:100j,zmin:zmax:100j]
    positions = np.vstack([X.ravel(),Y.ravel(),Z.ravel()])
    
    
    f = np.reshape(kernel(positions).T, X.shape)
    derivative = np.gradient(f)
    dz, dy, dx = derivative
    xdiff = np.sign(dx)   # along X-axis 
    ydiff = np.sign(dy)   # along Y-axis 
    zdiff = np.sign(dz)   # along Z-axis
    xcross = np.where(xdiff[:-1] != xdiff[1:])
    ycross = np.where([ydiff[:-1] != ydiff[1:]])
    zcross = np.where([zdiff[:-1] != zdiff[1:]])
    
    Zerocross =  xcross + ycross + zcross
    
  • X,Y=np.mgrid[xmin:xmax:100j,ymin:ymax:100j]
    positions=np.vstack([X.ravel(),Y.ravel(),Z.ravel()])
    as(kde文档)它们在可视化原始数据的真实估计时会有任何影响吗?。我真的不明白为什么我必须使用
    min
    max
    来执行KDE,然后使用
    ravel()

    这两条线建立了一个x、y、z位置的网格,KDE将在其中进行评估。在上面的代码中,它们仅用于估计核密度函数的导数。由于它们当前未用于任何与绘图相关的操作,因此不会影响可视化

    xmin
    xmax
    等用于确保网格覆盖数据中x、y、z值的全部范围。语法
    xmin:xmax:100j
    相当于
    np.linspace(xmin,xmax,100)
    ,即在
    xmin
    xmax
    之间返回100个均匀间隔的点

    np.mgrid
    返回的
    X
    Y
    Z
    数组将分别具有
    (100100100)
    ,而
    内核(位置)
    位置
    参数需要是
    (n_维度,n_点)
    。行
    np.vstack([X.ravel(),Y.ravel(),Z.ravel()])
    只是将
    np.mgrid
    的输出重新格式化为这种形式。将每个
    (100100100)
    数组展平为
    (1000000,)
    向量,并在第一个维度上连接它们以形成点的
    (310000)
    数组

    为什么我必须在
    f=np.reformate(kernel(positions).T,X.shape)

    您不需要:-)。
    kernel(positions)
    的输出是一个1D向量,因此对它进行转置将没有效果

    我未能用KDE估计和KDE估计/零交叉原始数据绘制原始数据:

    你试了什么?上面的代码似乎估计了核密度函数梯度的过零点,但不包括任何绘制它们的代码。你想画什么样的情节

    零交点应该是向量吗?。在下面的代码中,它是元组

    df = pd.read_csv(file, delimiter = ',')
    Convert series from data-frame into arrays
    X = np.array(df['x']) 
    Y = np.array(df['y']) 
    Z = np.array(df['z'])
    data = np.vstack([X, Y, Z])
    # perform KDE
    kernel = scipy.stats.kde.gaussian_kde(data)
    density = kernel(data)
    fig, ax = plt.subplots(subplot_kw=dict(projection='3d'))
    x, y, z = data
    scatter = ax.scatter(x, y, z, c=density)
    xmin = values[0].min()
    xmax = values[0].max()
    ymin = values[1].min()
    ymax = values[1].max()
    zmin = values[2].min()
    zmax = values[2].max()
    X,Y, Z =      np.mgrid[xmin:xmax:100j,ymin:ymax:100j,zmin:zmax:100j]
    positions = np.vstack([X.ravel(),Y.ravel(),Z.ravel()])
    
    
    f = np.reshape(kernel(positions).T, X.shape)
    derivative = np.gradient(f)
    dz, dy, dx = derivative
    xdiff = np.sign(dx)   # along X-axis 
    ydiff = np.sign(dy)   # along Y-axis 
    zdiff = np.sign(dz)   # along Z-axis
    xcross = np.where(xdiff[:-1] != xdiff[1:])
    ycross = np.where([ydiff[:-1] != ydiff[1:]])
    zcross = np.where([zdiff[:-1] != zdiff[1:]])
    
    Zerocross =  xcross + ycross + zcross
    
    当调用where
    x
    是多维数组时,将返回一个包含索引的元组,其中
    x
    为非零。自
    xdiff[:-1]!=xdiff[1://code>是一个3D数组,您将返回一个元组,其中包含三个1D索引数组,每个维度一个


    您可能不希望在
    np中使用额外的方括号集。其中([ydiff[:-1]!=ydiff[1:]])
    ,因为在这种情况下,
    [ydiff[:-1]!=ydiff[1:]
    将被视为
    (1100,100,100)
    数组,而不是
    (100,100,100)
    ,因此,您将得到一个包含4个索引数组而不是3个索引数组的元组(第一个数组将全部为零,因为第一个维度中的大小为1)。

    3-D数据加上密度总共是4维的。很难以有意义的方式将这些数据可视化。二维KDE非常容易实现(如果使用
    seaborn
    ,只需一行代码)。也许可以考虑通过PCA进行降维,而不损失太多的信息。因为<代码> SISPY.STATS。高斯- KDE < /代码>精确地计算KDE,永远不会有一个零交叉(除了无穷大)。你想解决什么问题?@JoeKington看起来她想估计核密度函数导数的过零点。非常感谢你的详细回答。但正如你提到的,网格用于导数,1)这是否会影响原始数据导数的正确过零?。我以散射(x,y,z,c=密度)绘制KDE结果。然而,2)我不知道展示流程的最佳方式;用KDE绘制原始数据,显示一阶导数和零交叉点(峰值),你能给我一些指导,告诉我如何显示原始数据到零交叉点的变化,以显示峰值吗?。3) 如果我想得到零交叉数,它应该是len(零交叉)?还有,4)100j或50j步进如何影响一阶导数?。当我为他们两个绘制散点图时。这些点位于X轴和Y轴上的相同位置,但其密度值略有变化。