如何根据用户的输入进行子集生成数据框?

时间:2019-07-18 07:52:24

标签: python pandas plotly plotly-dash

我正在尝试创建一个必须执行以下操作的Dash应用程序:

  1. 读取csv文件并将其转换为数据框
  2. 根据用户的选择对该数据框进行分组
  3. 在csv文件中生成子集数据框

我在特定情况下使用了两个数据帧gas3gas4

我想根据用户的选择基于gas_generegas3生成一个数据帧(gas4)。用户可以通过以下方式过滤数据框:

  1. 日期(DatePickerRange)
  2. 标记(单选按钮)
  3. 入口(清单)
  4. 温度最大值和最小值(输入)

包含此信息的所有变量都在gas3gas4中。这是一个“测试”代码(有些软件包在这里可能没用,请不要注意它们):

import dash
import dash_core_components as dcc # Graphs
import dash_html_components as html # Tags
from dash.dependencies import Input, Output, Event, State
import time
import pandas as pd
import plotly
import numpy as np
import statistics
from datetime import *
from pytz import *
import io
import urllib.parse

### Dataframe import

gas3 = pd.read_csv("C:/Path/gas3.csv", sep=';') # first data frame
gas4 = pd.read_csv("C:/Path/gas4.csv", sep=';') # second data frame
gas3['Date_Local_Time'] = pd.to_datetime(gas3['Date_Local_Time'], format='%Y/%m/%d %H:%M') # String to datetime
gas4['Date_Local_Time'] = pd.to_datetime(gas4['Date_Local_Time'], format='%Y/%m/%d %H:%M') # String to datetime

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets) # Starting application

app.layout = html.Div(children=[ # HTML of the entire project

### Date picker range

    html.Div([
            html.Label("Choose your time period :",
                    htmlFor='date_picker_range',
                    ),
            html.Br(),
            html.Br(),
            dcc.DatePickerRange(
                id='date-picker-range',
                min_date_allowed=gas3['Date_Local_Time'][0].date(),
                max_date_allowed=gas3['Date_Local_Time'][len(gas3)-1].date(),
                start_date=gas3['Date_Local_Time'][0].date(),
                end_date=gas3['Date_Local_Time'][len(gas3)-1].date(),
                start_date_placeholder_text='Start date',
                end_date_placeholder_text='End date',
                display_format = 'DD/MM/YYYY'
                ),
            html.Br(),
            html.Br()
            ]),

### Flag Choice

    html.Div([
            html.Label("Select a flag :",
                    htmlFor='radioflag',
                    ),
            html.Br(),
            html.Br(),
            dcc.RadioItems(
                    id='radioflag',
                    options=[
                        {'label': 'Flag 0', 'value': 'Flag0'},
                        {'label': 'Flag 1', 'value': 'Flag1'},
                        {'label': 'Flag 3', 'value': 'Flag3'},
                        {'label': 'Chambre à flux', 'value': 'CAF'}
                        ]
                        ),
            html.Br(),
            ]),

### Inlet(s) choice

    html.Div(children=[
            html.Label("Select one or several inlet(s) :",
                    htmlFor='checkbox_1',
                    ),
            html.Br(),
            html.Br(),
        html.Div(style={'width':'15%', 'height':'100%','float':'left'},
                children=[dcc.Checklist(id='ST1', className ='checkbox_1',
                        options=[
                            {'label': 'Inlet 1 ST1', 'value': 'I1ST1'},
                            {'label': 'Inlet 2 ST1', 'value': 'I2ST1'},
                            {'label': 'Inlet 3 ST1', 'value': 'I3ST1'},
                            {'label': 'Inlet 4 ST1', 'value': 'I4ST1'},
                            {'label': 'Inlet 5 ST1', 'value': 'I5ST1'},
                            {'label': 'Inlet 6 ST1', 'value': 'I6ST1'}
                                ],
                        values=[],
                        labelStyle = {'display': 'block'}
                                )
                        ]
                    ),

                ]
            ),

    html.Br(),
    html.Br(),
    html.Br(),
    html.Br(),

### Minimum temperature :

    html.Div(style={'width':'20%', 'height':'100%','float':'left'},
            children=[
            html.Label("Minimum temperature (°C) :",
                    htmlFor='tempmin',
                    ),
                       html.Br(),
            dcc.Input(
                    id = 'tempmin',
                    placeholder='Enter a value',
                    type='float',
                    value=''
                    )
            ]
            ),

### Maximum temperature :

    html.Div([
            html.Label("Maximum temperature (°C) :",
                    htmlFor='tempmax',
                    ),
                       html.Br(),
            dcc.Input(
                    id = 'tempmax',
                    placeholder='Enter a value',
                    type='float',
                    value=''
                    )
            ]
            ),

### Download button

    html.Div(id='table'),
    html.A(
        'Download Data',
        id='download-link',
        download="gas_genere.csv",
        href="",
        target="_blank"
    )
])

### Subset function

def filter_data(date1, date2, flag, ST1, tempmin, tempmax):   
    if flag == 'Flag0':
        gas_genere = gas3[gas3['Flag']==0]
    elif flag == 'Flag1':
        gas_genere = gas4.copy()
    elif flag == 'Flag3':
        gas_genere = gas3[gas3['Flag']==3]
    elif flag == 'CAF':
        gas_genere = gas3[gas3['3PV4']==1]
    else:
        gas_genere = gas3.copy()
    # gas_genere = gas_genere[(gas_genere['Temperature_air']>= tempmin) & (gas_genere['Temperature_air']<= tempmax)]
    # gas_genere = gas_genere[gas_genere['ST_Valve'] in ST1]
    # gas_genere = gas_genere[(gas_genere['Date_Local_Time'].time()>= date1) & (gas_genere['Date_Local_Time'].time()<= date2)]
    return gas_genere

### Callback :

@app.callback(
    Output('download-link', 'href'),
    [Input('date-picker-range', 'start_date'),
     Input('date-picker-range', 'end_date'),
     Input('radioflag', 'value'),
     Input('ST1', 'values'),
     Input('tempmin', 'value'),
     Input('tempmax', 'value')])

### Update download link

def update_download_link(date1, date2, flag, ST1, tempmin, tempmax):
    gas_genere = filter_data(date1, date2, flag, ST1, tempmin, tempmax)
    csv_string = gas_genere.to_csv(index=False, encoding='utf-8', sep=';')
    csv_string = "data:text/csv;charset=utf-8,%EF%BB%BF" + urllib.parse.quote(csv_string)
    return csv_string


if __name__ == '__main__':
    app.run_server(debug=True)

要对数据框进行子集化,请使用filter_data函数。但是效果不是很好!我在注释#中放入了所有无效的“过滤行”。 实际上,唯一起作用的是我的单选按钮来选择“标志”。通过选择所需的“标记”,我可以轻松生成一个csv文件:

Image1

但是我无法选择日期范围,最低/最高温度或一个/几个入口。如果我删除与这些行之一相对应的#,则得到的这种csv文件中充满了html代码:

Image2

我的代码怎么了?

0 个答案:

没有答案