翻译自 Create a data explorer app — Streamlit 0.71.0 documentation
1 创建一个 App
- 使用 vscode 新建文件
uber_pickups.py
,并载入一些包:
import streamlit as st
import pandas as pd
import numpy as np
- 每个好的应用都有标题,因此我们添加一个标题:
st.title('Uber pickups in NYC')
- 现在是时候从命令行运行 Streamlit 了:
streamlit run uber_pickups.py
- 该应用程序应在浏览器的新标签页中自动打开。
2 获取一些数据
现在您已经有了一个应用程序,接下来要做的就是获取纽约市的 Uber 接送服务的数据集。
- 首先,编写一个加载数据的函数。将此代码添加到脚本中:
DATE_COLUMN = 'date/time'
DATA_URL = ('https://s3-us-west-2.amazonaws.com/'
'streamlit-demo-data/uber-raw-data-sep14.csv.gz')
def load_data(nrows):
data = pd.read_csv(DATA_URL, nrows=nrows)
lowercase = lambda x: str(x).lower()
data.rename(lowercase, axis='columns', inplace=True)
data[DATE_COLUMN] = pd.to_datetime(data[DATE_COLUMN])
return data
注意到,load_data
是一个普通的旧函数,它下载一些数据,将其放入 Pandas 数据框中,然后将 date 列从文本转换为 datetime
。
# 获取数据集
DATE_COLUMN = 'date/time'
DATA_URL = ('https://s3-us-west-2.amazonaws.com/'
'streamlit-demo-data/uber-raw-data-sep14.csv.gz')
def load_data(data_url, nrows, date_column):
data = pd.read_csv(data_url, nrows=nrows)
lowercase = lambda x: str(x).lower()
data.rename(lowercase, axis='columns', inplace=True)
data[date_column] = pd.to_datetime(data[date_column])
return data
- 现在,我们测试一下功能并查看输出。在函数下方,添加以下行:
# Create a text element and let the reader know the data is loading.
data_load_state = st.text('载入数据中...')
# Load 10,000 rows of data into the dataframe.
data = load_data(DATA_URL, 10000, DATE_COLUMN)
# Notify the reader that the data was successfully loaded.
data_load_state.text('载入数据...完成!')
您会在应用程序的右上角看到一些按钮,询问您是否要重新运行该应用程序。选择“Always rerun”,每次保存时,您都会自动看到所做的更改。
事实证明,下载数据和将 10,000 行加载到数据框中需要花费很长时间。将日期列转换为日期时间也不是一件容易的事。您不想每次更新应用程序时都重新加载数据–幸运的是,Streamlit 允许您缓存数据。
3 轻松的缓存
- 尝试添加
@st.cache
来装饰load_data
函数:
@st.cache
def load_data(data_url, nrows, date_column):
- 然后保存脚本,Streamlit 将自动重新运行您的应用程序。由于这是您第一次使用
@st.cache
运行脚本,因此您不会看到任何更改。让我们稍微调整一下文件,以便您了解缓存的功能。 - 将以下行替换为
data_load_state.text('载入数据...完成!')
:
data_load_state.text("完成了!(使用st.cache)")
- 现在保存。看到添加的行如何立即出现? 如果退后一秒,这实际上是相当了不起的。幕后发生了一些神奇的事情,只需一行代码即可激活它。
4 缓存的工作原理
让我们花一些时间来讨论 @st.cache
的实际工作方式。
当用 Streamlit 的缓存注释标记一个函数时,它告诉 Streamlit 每当调用该函数时,它应该检查三件事:
- 组成函数主体的实际字节码
- 函数依赖的代码,变量和文件
- 您用来调用函数的输入参数
如果这是 Streamlit 第一次看到具有这些确切值的项,并且以这种确切的组合,它将运行该函数并将结果存储在本地缓存中。下次调用该函数时,如果三个值都没有更改,则 Streamlit 知道它可以完全跳过执行该函数。 取而代之的是,它从本地缓存中读取输出,然后像魔术一样将其传递给调用方。
这么神奇,怎么做到的?好吧,我们看看细节:
好吧,有几个:
- Streamlit 将仅检查当前工作目录中的更改。如果您升级 Python 库,则只有在该库安装在您的工作目录中时,Streamlit 的缓存才会注意到这一点。
- 如果您的函数不是确定性的(也就是说,其输出取决于随机数),或者如果它从外部时变源(例如,实时股票行情报价服务)中提取数据,则缓存的值将是 none-the-wiser。
- 最后,您不应更改缓存功能的输出,因为缓存值是按引用存储的(出于性能原因,并且能够支持TensorFlow等库)。请注意,在这里,Streamlit 足够聪明,可以检测到这些突变并显示响亮的警告,说明如何解决问题。
尽管要牢记这些限制很重要,但在很多时候它们往往不会成为问题。那些时候,此缓存确实具有变革性。
TIP:只要您的代码中运行了长时间的计算,请考虑对其进行重构,以便在可能的情况下使用
@st.cache
。
现在您已经知道 Streamlit 的缓存是如何工作的,让我们回到 Uber 的接送数据。
5 检查原始数据
在开始使用原始数据之前,最好先查看一下要使用的原始数据。让我们向应用添加子标题和原始数据的打印输出:
st.subheader('原始数据')
st.write(data)
6 绘制直方图
现在,您已经有机会查看数据集并观察可用数据,让我们更进一步,并绘制直方图,查看 Uber 在纽约市最忙的时间。
- 首先,让我们在原始数据部分的下方添加一个子标题:
st.subheader('每小时接送次数')
- 使用 NumPy 生成直方图,以分解按小时划分的接送时间:
hist_values = np.histogram(
data[DATE_COLUMN].dt.hour, bins=24, range=(0, 24))[0]
- 现在,让我们使用 Streamlit 的
st.bar_chart()
方法绘制此直方图。
st.bar_chart(hist_values)
- 保存脚本。此直方图应立即显示在您的应用中。经过快速审核后,看来最忙的时间是 17:00(下午5点)。
要绘制此图,我们使用了 Streamlit 的 bar_chart()
方法,但重要的是要知道 Streamlit 支持更复杂的图表库,例如 Altair,Bokeh,Plotly,Matplotlib 等。有关完整列表,请参见支持的图表库。
7 在地图上绘制数据
在 Uber 的数据集中使用直方图可以帮助我们确定最繁忙的接送时间,但是如果我们想弄清整个城市接送的地点最集中,该怎么办。尽管您可以使用条形图来显示此数据,但是除非您非常熟悉城市中的纬度和经度坐标,否则就不容易理解。为了显示接送浓度,让我们使用 Streamlit 的 st.map()
函数将数据覆盖在纽约市的地图上。
st.subheader('地图上的接送')
st.map(data)
效果:
绘制直方图时,已确定 Uber 的最繁忙时间是17:00。让我们重新绘制地图,以显示 17:00 的接客浓度。
要绘制此地图,我们使用了 Streamlit 内置的 st.map
函数,但是如果您想可视化复杂的地图数据,建议您看一下 st.pydeck_chart
。
8 使用滑块过滤结果
在上一部分中,当您绘制地图时,用于过滤结果的时间被硬编码到脚本中,但是如果我们想让读者实时地动态过滤数据该怎么办?您可以使用 Streamlit 的小部件。让我们使用 st.slider()
方法向应用添加滑块。
hour_to_filter = st.slider('hour', 0, 23, 17) # min: 0h, max: 23h, default: 17h
效果:
9 使用按钮切换数据
滑块只是动态更改应用程序组成的一种方法。让我们使用 st.checkbox
函数向您的应用添加一个复选框。我们将使用此复选框在应用程序顶部显示/隐藏原始数据表。
if st.checkbox('Show raw data'):
st.subheader('Raw data')
st.write(data)
网友评论