用Django将上传的csv文件使用pandas进行处理并返回

首先

我是一位正在学习Python数据处理和机器学习的初学者。

我已经创建了一个应用程序,使用了我们创建的回归模型,它可以读取上传的测试文件并在Notebook中使用pandas进行数据处理。然后,我将处理结果保存为CSV文件,并添加了一个在网络上下载该文件的功能。

我在那时遇到了很多困难,直到读取和返回 CSV 文件的过程才顺利进行。

在网络上,关于如何在Django中使用pandas的方法并不常见,我在研究了很多资料并进行尝试后,完全按照自己的方法完成了这个项目,所以可能存在一些不足之处,请多多包涵。

环境和前提

Windows10
Django 3.1.7
Python 3.9.2

Windows10
Django 3.1.7
Python 3.9.2

Windows10
Django 3.1.7
Python 3.9.2

    プロジェクト作成
$ django-admin startproject myproject
$ cd myproject
$ python manage.py startapp app
    ディレクトリ構成
myproject/
  app/
    __pycache__/
    migrations/
    static/
      files/ (new)
        train_x.csv
        train_y.csv
    __init__.py
    admin.py
    apps.py
    forms.py (new)
    functions.py (new)
    models.py
    tests.py
    views.py
  myproject/
    __pycache__/
    __init__.py
    asgi.py
    settings.py
    urls.py
    wsgi.py
static/
templates/
  index.html
db.sqlite3
manage.py

image.jpg

创建表单

创建forms.py文件。

from django import forms

class UploadForm(forms.Form):
    testfile = forms.FileField()

当在HTML中使用时,会生成一个选择文件的表单。

<div class="form-group">
  <form method="POST" class="form" enctype="multipart/form-data">  
    {% csrf_token %}  
    <div class="file-upload-wrapper">
      <p>テストファイルを選択<br \>
        {{ form.testfile }}
      </p>   
    </div> 

最终设置urls.py。

from django.contrib import admin
from django.urls import path
from app import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.index, name='index'), (追加)
]

settings.py的配置

# 省略

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app', # 追加
]
# 省略
TEMPLATES = [
    {
        # 省略
        'DIRS': [BASE_DIR, 'templates'],
        # 省略
    },
]

当您执行 $python manage.py runserver 后在本地主机上访问时,会出现文件选择的表单。

上传文件的处理

这次我们将在functions.py中编写文件处理的函数,并在views.py中使用它们。

from django.shortcuts import render
from django.http import HttpResponse
from django.template import loader
from app.forms import UploadForm
from app.functions import process_file,to_csv
import csv,io
import pandas as pd

# Create your views here.
def index(request):
    if request.method == 'POST':
        upload = UploadForm(request.POST, request.FILES)
        if upload.is_valid():
            data = pd.read_csv(io.StringIO(request.FILES['testfile'].read().decode('utf-8')), delimiter=',')
            df = process_file(data)

            response = to_csv(df)

            return response
    else:
        upload = UploadForm()
        return render(request, "index.html", {'form':upload})

data = pd.read_csv(io.StringIO(request.FILES[‘testfile’].read().decode(‘utf-8′)), delimiter=’,’)

単にpd.read_csvだけでは読み取れず、いろいろ試しまくった結果これでcsvの読み取りができました。

process_file():pandasでデータを処理

to_csv():データフレームをcsvファイルにしてダウンロード

数据处理和下载

import pandas as pd
import numpy as np
import sklearn,csv,re,os
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from django.http import HttpResponse
from myproject.settings import BASE_DIR

def process_file(data):
    train_x = pd.read_csv(os.path.join(BASE_DIR, 'app/static/files/train_x.csv'))
    train_y = pd.read_csv(os.path.join(BASE_DIR, 'app/static/files/train_y.csv'))
    test = data
    
    # 自由にデータ処理

    # 最後にデータフレームとして返す
    df_result = ...

    return df_result

def to_csv(df):
    response = HttpResponse(content_type='text/csv; charset=UTF-8')
    response['Content-Disposition'] = 'attachment; filename="result.csv"'
    
    df.to_csv(path_or_buf = response, encoding = 'utf-8-sig', index=False)
    
    return response

データ処理に必要なモジュールをそれぞれインポート

process_file()

trainデータをmyproject/app/static/files/から読み込み
ローカルではpd.read_csv(“app/static/files/~”)でも可能
サーバーにデプロイするときはBASE_DIR/app/static/files/~となるように設定
(ちなみにBASE_DIRはsettings.pyで定義され、デフォルトではmanage.pyの存在するディレクトリ。この例ではmyproject/になります。)
Notebookで行っているような処理を自由に、最後にデータフレーム型で返してあげます。

to_csv()

process_fileから返却されたデータフレームをcsvに変換しダウンロード
HttpResponseとして”result.csv”という名前のcsvファイルを返す
attachmentをつけることで、フォームのボタンをクリックすると自動的にダウンロードが開始

path_or_buf = responseとすることでデータフレームをcsvに変換できるように

<div class="form-group">
  <form method="POST" class="form" enctype="multipart/form-data">  
    {% csrf_token %}  
    <div class="file-upload-wrapper">
      <p>テストファイルを選択<br \>
        {{ form.testfile }}
      </p>
    </div> 
    <p>テストファイルをアップロードし、予測結果の'result.csv'ファイルをダウンロードする</p>
    <button type="submit" class="save btn btn-outline-primary">Upload and Download</button>  
  </form> 
</div>

在表单中添加按钮以完成

填充

アップロードされたファイルの形式チェック等は省略しています。

Djangoでpandasを使用する方法を調べていると、django-pandasというライブラリをインストールして使うという説明しか見当たらなかったのですが、python標準モジュールのpandasでもなんとかできました。

bannerAds