VisibleDeprecationWarning:一个关于List创建ndarray的警告
Warning的出现
本人在白嫖数据分析课程时,老师在课堂上出现的一个迷惑性报错。可惜的是老师在课堂上并未找出和说明原因,只是单方面的删除了对一个方法的使用。
# 导入第三方库
import pandas as pd
import numpy as np
# 文件路径
file_path='./archive_03/IMDB-Movie-Data.csv'
#pandas读取csv文件
movie = pd.read_csv(file_path)
# 目的:获取演员的人数
temp_actors_list = movie['Actors'].str.split(',').tolist()
# 这里是DataFrame中的演员并做切割处理,转话为列表
actors_list = list(np.array(temp_actors_list).flatten())
# 由于temp_actors_list为列表里面还有一个列表的形式,
# 这里通过np.array()转为数组形式并且flatten展开为一维数组
actors_num = len(set(actors_list)) #set()转为集合去重,最后len()查列表长度
print(actors_num) #打印结果
想法固然美好,但出现了Warning
:
Warning
的出现,只是删除方法去解决,不能使我满足。我更想知道为什么会出现Warning
?如何避免再出现Warning
?
为什么会出现Warning?
首先,我们先通过百度翻译,翻译以下Warning
:
VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray. actors_list = list(np.array(temp_actors_list).flatten())
得到中文:
到这里,我们已经可以了解大概的原因了,似乎是我们在创建ndarray
时,没有使用相同长度的列表造成Warning
,最后导致了后面TypeError
.
接下来,我们进行基本的debug
操作:
1.查看以下代码:
actors_list = list(np.array(temp_actors_list).flatten())
创建ndarray
,我们这里使用的是np.array(temp_actors_list)
。也就是说,temp_actors_list里面的列表长度并不统一?!
2.使用print()
寻找证据
print(temp_actors_list)
计算机返还结果:
我们可以看到,返回的是双重嵌套列表形式。
继续寻找整个列表里包含的列表的长度不同的证据:
# 这里本人使用for遍历
for i in temp_actors_list:
# 在建立一个循环,当当前列表和下一个列表长度不相同时,
if len(i)!=len(temp_actors_list[temp_actors_list.index(i)+1]):
#打印False且打印出两个列表的长度
print('False')
print(len(i))
print(len(temp_actors_list[temp_actors_list.index(i)+1]))
break
计算机返还结果:
经过上述认证,已经可以确认Warning
的来源,即该列表内的全部列表的长度不统一。
那么,TypeError也可以确定了
我们知道,Warning是只是Warning,并非Error。
由于上述代码不便于说明,这里使用ipython
进行简单案例来讲说。(in
为输入,out
为输出,#
为注释)
In [1]: import numpy as np
In [2]: x=[[1,2],[3,4,5]]
# 不同长度的列表
In [3]: x
Out[3]: [[1, 2], [3, 4, 5]]
In [4]: t1=np.array(x)
# 将x强行赋值给np.array(),得到Warning
<ipython-input-4-cb670f51a5c6>:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
t1=np.array(x)
# 不理会Warning,进行flatten操作。得到一个dtype=object的ndarray
In [5]: t1.flatten()
Out[5]: array([list([1, 2]), list([3, 4, 5])], dtype=object)
# 转化为list,与原先的x一模一样。相当于没操作!
In [6]: list(t1.flatten())
Out[6]: [[1, 2], [3, 4, 5]]
# set()不接受x这样的列表,为hash错误。
In [7]: set(list(t1.flatten()))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-81a27ceeb301> in <module>
----> 1 set(list(t1.flatten()))
TypeError: unhashable type: 'list'
现在可以将这个方法就地正法了!
如何去解决Warning?
这是一个有意思的开放性的话题,本人也没有明确的答案(主要小编也只是在python
门口)。但贵在尝试,因此在这里交上自己的一份答卷。
之前的翻译中,告诉我们:
“如果您打算这样做,则在创建ndarray
时必须指定’dtype=object
‘。”
进行尝试:
In [14]: x
Out[14]: [[1, 2], [3, 4, 5]]
In [15]: t2=np.array(x,dtype='object')
# 虽然没有了Warning,但并没有解决问题
In [16]: t2
Out[16]: array([list([1, 2]), list([3, 4, 5])], dtype=object)
In [17]: list(t2.flatten())
Out[17]: [[1, 2], [3, 4, 5]]
是的!尽管没有了Warning
,但是得到的结果并没有什么改变!
因此,小编建议大家还是尽可能地不去使用这种列表创建ndarray
!
希望您能解决这个Warning
!
希望您能有所收获!
希望能与诸君共同进步!
最后来个赞呗!👍