今天在数据分析的过程中碰上一个奇葩的问题(如标题所示)。
背景:我需要把一个数组,由30个一级元素(代表一个月的30天),每个一级元素包含了3种二级元素,每一个二级元素包含了24种三级元素(代表一天的24个小时)。我一开始想着这么庞大的数组手动建立太麻烦了,写个循环创立简单很多,代码如下:
day=[]
for i in range(0,24):#三级元素数组
day.append(0)
for i in range(0,30):#一级元素数组
data.append([day,day,day])
看着逻辑挺顺,但,这就是万恶的开始,在空数组创立阶段就埋下了炸弹。
可惜问题就是,当我赋值其中一个基本元素的时候,其他的元素也跟着变化:比如改变data[26][1][9],就会发现所有的[1][9]都变了,从1到30全部都变了。。
吾上下而求索,发现是地址的问题!
print(id(data))
print(id(day))
print(id(data[0][0]))
print(id(data[0][1]))
print(id(data[0][2]))
print(id(data[5][0]))
print(id(data[9][1]))
print(id(data[20][2]))
print(id(data[26][0]))
>>>140429613426056
>>>140429613425928
>>>140429613425928
>>>140429613425928
>>>140429613425928
>>>140429613425928
>>>140429613425928
>>>140429613425928
>>>140429613425928
这就是问题的根源所在,所有的二级元素都共享同一个数组(地址相同),当让会改一个基本单元,其他的数组就跟着变化了啦!~~
解决方案:
最朴素的解决方法就是手动(当时为了避免繁琐果断抛弃,如今真香~)。
for i in range(0,30):
data.append([
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
])
print(data[0][0])
print(data[1][2])
print(data[2][1])
print(data[24][0])
>>>140669134329544
>>>140669134330120
>>>140669134330440
>>>140669134324552
看有没有感觉不一样~
或者你要是觉得实在不想手动打那么多的零(零异事件),numpy的zeros可以拯救。比如np.zeros(24)就等于上面的那么多个零啦!