从嵌套字典创建2D数组

时间:2016-08-04 15:18:05

标签: python arrays dictionary multidimensional-array matplotlib

我是第一次使用python词典的学生,我不得不依赖于矩阵阵列。

我有一个嵌套的有序字典,用于逐周描述温度和湿度。

weather = OrderedDict([(92, OrderedDict([('Mon', 79), ('Tues', 85), 
          ('Weds', 87), ('Thurs', 83)])), 
          (96, OrderedDict([('Mon', 65), ('Tues', 71), 
          ('Weds', 74), ('Thurs', 68)])), 
          (91, OrderedDict([('Mon', 83), ('Tues', 84), 
          ('Weds', 82), ('Thurs', 80)]))])

每周的总体关键字表示平均湿度,每天的个别值是温度。

我正在尝试在matplotlib中创建一个温度与日线的单个图形图,它将使用湿度作为第三个变量来指示颜色条的颜色。似乎LineCollection将使用日期和温度的2D数组执行此操作。但是当我尝试从嵌套字典中提取2D数组时,我似乎无法将其变为LineCollection所需的Nx2形状。

非常感谢任何帮助!

这是我到目前为止的代码:

plt.figure()
x=[]
y=[]
z=[]
ticks=[]
for humidity, data_dict in weather.iteritems():
    x.append(range(len(data_dict)))
    y.append(data_dict.values())
    z.append(humidity)
    ticks.append(data_dict.keys())
for ii in x,y,z:
    ii = np.array(ii)
lines=np.array(zip(x,y))
print lines.shape

这会返回形状为(3,2,4)而不是(3,2)

编辑: 我希望输出中的行看起来像这样,所以numpy可以将它识别为3x2 2D数组:

 [[(0 1 2 3), (79 85 87 83)],
  [(0 1 2 3), (65 71 74 68)],
  [(0 1 2 3), (83 84 82 80)]]

3 个答案:

答案 0 :(得分:2)

您需要遍历嵌套字典,将值附加到列表中。您还应该存储日期编号,以便能够绘制温度。湿度的颜色也应该存储在每一天。然后,您需要定义轴标签以将天数显示为字符串。执行此操作的代码如下所示,

from collections import OrderedDict
import matplotlib.pyplot as plt

weather = OrderedDict([(92, OrderedDict([('Mon', 79), 
                                         ('Tues', 85), 
                                         ('Weds', 87), 
                                         ('Thurs', 83)])), 
                       (96, OrderedDict([('Mon', 65), 
                                         ('Tues', 71), 
                                         ('Weds', 74), 
                                         ('Thurs', 68)])), 
                       (91, OrderedDict([('Mon', 83), 
                                         ('Tues', 84), 
                                         ('Weds', 82), 
                                         ('Thurs', 80)]))])
Temp = []
Humidity = []
Day = []
Dayno = []
for h, v in weather.items():
    j = 0
    for d, T in v.items():
        Temp.append([T])
        Humidity.append([h])
        Day.append([d])
        Dayno.append([j])
        j += 1

fig,ax = plt.subplots(1,1)
cm = ax.scatter(Dayno, Temp, c=Humidity, 
                vmin=90., vmax=100., 
                cmap=plt.cm.RdYlBu_r)
ax.set_xticks(Dayno[0:4])
ax.set_xticklabels(Day[0:4])
plt.colorbar(cm)
plt.show()

哪个情节,

enter image description here

更新:如果要使用绘图,则需要将数据分成每周一个数组,然后将这些数据绘制为单行。然后,您可以为每行和标签设置颜色。我使用numpy和数组切片附加了一个版本(虽然可能不是最简单的解决方案),

from collections import OrderedDict
import matplotlib.pyplot as plt
import matplotlib
import numpy as np

weather = OrderedDict([(92, OrderedDict([('Mon', 79), 
                                         ('Tues', 85), 
                                         ('Weds', 87), 
                                         ('Thurs', 83)])), 
                       (96, OrderedDict([('Mon', 65), 
                                         ('Tues', 71), 
                                         ('Weds', 74), 
                                         ('Thurs', 68)])), 
                       (91, OrderedDict([('Mon', 83), 
                                         ('Tues', 84), 
                                         ('Weds', 82), 
                                         ('Thurs', 80)]))])
Temp = []; Humidity = []
Day = []; Dayno = []; weekno = []
i = 0
for h, v in weather.items():
    j = 0
    for d, T in v.items():
        Temp.append(T)
        Humidity.append(h)
        Day.append(d)
        Dayno.append(j)
        weekno.append(i)
        j += 1
    i += 1

#Swtich to numpy arrays to allow array slicing
Temp = np.array(Temp)
Humidity = np.array(Humidity)
Day = np.array(Day)
Dayno = np.array(Dayno)
weekno = np.array(weekno)

#Plot lines
fig,ax = plt.subplots(1,1)
vmin=90.; vmax=97.; 
weeks=3; daysperweek=4
colour = ['r', 'g', 'b']
for i in range(weeks):
    ax.plot(Dayno[weekno==i], 
            Temp[weekno==i], 
            c=colour[i], 
            label="Humidity = " + str(Humidity[daysperweek*i]))

ax.set_xticks(Dayno[0:4])
ax.set_xticklabels(Day[0:4])
plt.legend(loc="best")
plt.show()

看起来像, enter image description here

答案 1 :(得分:1)

如果只是你想要的情节,这可能会有所帮助

from collections import OrderedDict 
import matplotlib.pyplot as plt

weather = OrderedDict([(40, OrderedDict([('Mon', 79), ('Tues', 85), 
      ('Weds', 87), ('Thurs', 83)])), 
      (90, OrderedDict([('Mon', 65), ('Tues', 71), 
      ('Weds', 74), ('Thurs', 68)])), 
      (99, OrderedDict([('Mon', 83), ('Tues', 84), 
      ('Weds', 82), ('Thurs', 80)]))])

humidity = []
temp = []
days = []

for humid,daytempdict in weather.iteritems():
    humidity.append(humid)
    days.append(range(len(daytempdict)))
    temp.append(daytempdict.values())

for (t,d,i) in zip(temp,days,humidity):   
    #normalize humidity by max humidity
    c = float(i)/max(humidity)
    #color according to the normalized humidity, shade of red
    c = tuple((1*  c ,0,0))   
    plt.plot(d,t,color=c,label="humidity "+str(i) )

plt.xlabel("days")
plt.ylabel("tempreture")
plt.legend(loc="best")
plt.show()          

The plot looks like this

答案 2 :(得分:0)

如果你想要一个2D数组,你需要用x和y连接你的范围而不是追加。你没有得到你想要的输出的原因是x.append(list)将列表作为x的元素插入 - 这意味着你有

[[0, 1, 2, 3], [0, 1, 2, 3],...] 

当你想要的时候

[0,1,2,3,0,...]

像这样修改你的for循环应该产生一个(12,2)天数和温度数组:

for humidity, data_dict in weather.iteritems():
    x = x + range(len(data_dict))
    y = y + (data_dict.values())