从散点图到2D阵列

时间:2016-09-13 16:45:12

标签: python arrays numpy matplotlib

我的思绪在这个问题上完全是空白。

我想做我认为很简单的事情。

假设我有一些测试数据:

import pandas as pd
import numpy as np
k=10
df = pd.DataFrame(np.array([range(k), 
                           [x + 1 for x in range(k)],
                           [x + 4 for x in range(k)], 
                           [x + 9 for x in range(k)]]).T,columns=list('abcd'))

其中行对应于时间,列对应于角度,它看起来像这样:

   a   b   c   d
0  0   1   4   9
1  1   2   5  10
2  2   3   6  11
3  3   4   7  12
4  4   5   8  13
5  5   6   9  14
6  6   7  10  15
7  7   8  11  16
8  8   9  12  17
9  9  10  13  18

然后由于原因我将其转换为有序词典:

def highDimDF2Array(df):
    from collections import OrderedDict # Need to preserve order

    vels = [1.42,1.11,0.81,0.50]

    # Get dataframe shapes
    cols = df.columns

    trajectories = OrderedDict()
    for i,j in enumerate(cols):
        x = df[j].values
        x = x[~np.isnan(x)]

        maxTimeSteps = len(x)
        tmpTraj = np.empty((maxTimeSteps,3))
        # This should be fast
        tmpTraj[:,0] = range(maxTimeSteps) 
        # Remove construction nans
        tmpTraj[:,1] = x
        tmpTraj[:,2].fill(vels[i])

        trajectories[j] = tmpTraj

    return trajectories

然后我全部绘制

import matplotlib.pyplot as plt
m = highDimDF2Array(df)
M = np.vstack(m.values())
plt.scatter(M[:,0],M[:,1],15,M[:,2])
plt.title('Angle $[^\circ]$ vs. Time $[s]$')
plt.colorbar()
plt.show()

enter image description here

现在我想做的就是把所有这些都放到一个带有属性的2D numpy数组中:

  • 时间映射到x轴(或y无关紧要)
  • 角度映射到y轴
  • 矩阵中的条目对应于散点图中的彩色点值
  • 所有其他条目都被视为NaNs(即散点图中某个点未定义的条目)

在3D中,颜色与高度相对应。

我在考虑使用这样的东西:3d Numpy array to 2d但是我不太确定如何。

2 个答案:

答案 0 :(得分:2)

您可以将M [:,1]和M [:,2]中的值转换为整数,并将它们用作2D numpy数组的索引。这是使用您定义的M的值的示例。

out = np.empty((20,10))
out[:] = np.NAN
N = M[:,[0,1]].astype(int)
out[N[:,1], N[:,0]] = M[:,2]
plt.scatter(M[:,0],M[:,1],15,M[:,2])
plt.scatter(M[:,0],M[:,1],15,M[:,2])
plt.title('Angle $[^\circ]$ vs. Time $[s]$')
plt.colorbar()
plt.imshow(out, interpolation='none', origin = 'lower')

enter image description here

在这里你可以直接将M转换为整数,但你可能需要提供一个函数来将M的列映射到整数,具体取决于你正在创建的数组的分辨率。

答案 1 :(得分:1)

我不使用熊猫,所以我无法真正遵循你的功能。但是从你的阵列M的描述和你想要的东西,我认为funktion np.histogram2d就是你想要的。它以等距步骤对您的独立值范围进行分类,并对所有事件进行求和。您可以使用第3列进行加权以获得适当的高度。您必须选择垃圾箱数量:

z, x, y   = np.histogram2d(M[:,0], M[:,1], weights=M[:,2], bins=50)
num, x, y = np.histogram2d(M[:,0], M[:,1], bins=50)

z /= num # proper averaging, it also gives you NaN where num==0

plt.pcolor(x, y, z) #visualization

同样plt.hist2d可能很有趣

修改 histogram2d产生问题中要求的2D数组。然而,可视化应该用imshow完成,因为pcolor不会跳过NaN值(有什么方法可以教它吗?)

此方法的优点是x,y值可以是浮点数和任意顺序。此外,通过定义箱的数量,可以选择所得图像的分辨率。 然而,为了得到所要求的结果,人们应该这样做:

binx = np.arange(M[:,0].min()-0.5, M[:,0].max()+1.5) # edges of the bins. 0.5 is the half width
biny = np.arange(M[:,1].min()-0.5, M[:,1].max()+1.5)

z,   x, y   = np.histogram2d(M[:,0], M[:,1], weights=M[:,2], bins=(binx,biny))
num, x, y   = np.histogram2d(M[:,0], M[:,1], bins=(binx,biny))

z /= num


plt.imshow(z.T, interpolation='none', origin = 'lower')

enter image description here

pcolor的输出不会遗漏nans但因此也会考虑x和y值:

plt.pcolormesh(x, y, z.T, vmin=0, vmax=2)

enter image description here