Python Pandas - Read CSV or Excel



我允许用户上传CSV或Excel文件。我正在使用panda读取文件并创建一个数据帧。由于我无法预测用户将上传哪种文件类型,所以我将pd.read_csv()和pd.read_excel()封装在一个try/except块中。

if form.validate_on_submit():
input_filename = secure_filename(form.file.data.filename)
try:
df = pd.read_csv(form.file.data, header=0, skip_blank_lines=True, skipinitialspace=True, encoding='latin-1')
except:
df = pd.read_excel(form.file.data, header=0, skip_blank_lines=True, skipinitialspace=True, encoding='latin-1')

如果pd.read_csv()是try/except块中的第一个,并且我上传了一个.csv文件,它就可以工作了。如果我试图上传.xlsx文件,我会收到以下错误:

TypeError: expected str, bytes or os.PathLike object, not NoneType

如果pd.read_excel()是try/except块中的第一个,并且我上传了一个.xlsx文件,它就可以工作了。如果我试图上传.csv文件,我会收到以下错误:

pandas.io.common.EmptyDataError: No columns to parse from file

以前,我使用mimetype将文件路由到正确的panda函数,但我希望有一个更干净(包罗万象)的解决方案,不涉及几个if/elif语句。这就是我所拥有的:

if form.file.data.mimetype == 'text/csv':
df = pd.read_csv(form.file.data, header=0, skip_blank_lines=True, skipinitialspace=True, encoding='latin-1')
elif form.file.data.mimetype == 'application/octet-stream':
df = pd.read_excel(form.file.data, header=0, skip_blank_lines=True, skipinitialspace=True, encoding='latin-1')
elif form.file.data.mimetype == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
df = pd.read_excel(form.file.data, header=0, skip_blank_lines=True, skipinitialspace=True, encoding='latin-1')
else:
flash('Error Uploading File. Invalid file type. Please use xls, xlsx or csv.', 'danger')
return render_template('upload.html', current_user=current_user, form=form)

我使用的是Flask、WTForms和Python 3。非常感谢。

您使用关键字args调用read_excel,这些参数对read_csv有用,但read_excel不支持。相反,您可以尝试:

if form.validate_on_submit():
input_filename = secure_filename(form.file.data.filename)
data = form.file.data
try:
df = pd.read_csv(data, header=0, skip_blank_lines=True, 
skipinitialspace=True, encoding='latin-1')
except:
df = pd.read_excel(data, header=0)

除了删除read_excel的额外args之外,我还提升了从form.file.data中提取数据的功能;这是为了克服可能存在一些与try/except块交互不良的惰性负载行为的可能性。

通常,在web请求中很难调试中等复杂的I/O功能。当这样的操作不起作用时,最好的方法是将问题分为两部分:1/从web请求中获取数据,并将其写入文件。然后,2/分别从生成的文件中尝试I/O(在本例中为Pandas数据帧加载)。以交互方式或在单独的程序中执行此操作将为您提供更多的调试机会和清晰度。Jupyter Notebook非常适合这种探索性测试,尽管大多数IDE甚至裸Python REPL都可以工作。当第2/部分明显有效时,您可以在Flask/web应用程序代码下将其重新修补。

最新更新