Spaces:
Sleeping
Sleeping
File size: 6,336 Bytes
e522499 cdf0803 01ac828 cdf0803 15c01f8 cdf0803 1ce52fb cdf0803 1ce52fb cdf0803 15c01f8 cdf0803 01ac828 cdf0803 01ac828 cdf0803 01ac828 cdf0803 01ac828 cdf0803 15c01f8 cdf0803 15c01f8 cdf0803 15c01f8 cdf0803 15c01f8 cdf0803 15c01f8 cdf0803 15c01f8 cdf0803 01ac828 15c01f8 cdf0803 a1d5478 cdf0803 15c01f8 cdf0803 15c01f8 cdf0803 15c01f8 cdf0803 15c01f8 cdf0803 15c01f8 cdf0803 01ac828 cdf0803 01ac828 15c01f8 cdf0803 15c01f8 cdf0803 01ac828 cdf0803 15c01f8 cdf0803 15c01f8 cdf0803 15c01f8 cdf0803 e522499 cdf0803 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
import streamlit as st
import pandas as pd
import numpy as np
# 设置页面布局为宽屏模式,并设置页面标题
st.set_page_config(layout="wide", page_title="影城排片效率分析")
def clean_movie_title(title):
"""
清理并规范化电影标题。
根据用户最新指示:只保留字符串中第一个空格之前的部分。
"""
if not isinstance(title, str):
return title
# 将标题按第一个空格分割,并只取第一部分
return title.split(' ', 1)[0]
def style_efficiency(row):
"""
根据效率值高亮特定行。
高于 1.5 的淡绿色,低于 0.5 的淡红色。
"""
# 定义颜色
green = 'background-color: #E6F5E6;' # 淡绿色
red = 'background-color: #FFE5E5;' # 淡红色
default = ''
# 初始化样式列表,长度与行内元素数量一致
styles = [default] * len(row)
# 获取效率值
seat_efficiency = row.get('座次效率', 0)
session_efficiency = row.get('场次效率', 0)
# 判断并应用样式
if seat_efficiency > 1.5 or session_efficiency > 1.5:
styles = [green] * len(row)
elif seat_efficiency < 0.5 or session_efficiency < 0.5:
styles = [red] * len(row)
return styles
def process_and_analyze_data(df):
"""
核心数据处理与分析函数。
"""
if df.empty:
return pd.DataFrame()
analysis_df = df.groupby('影片名称_清理后').agg(
座位数=('座位数', 'sum'),
场次=('影片名称_清理后', 'size'),
票房=('总收入', 'sum'),
人次=('总人次', 'sum')
).reset_index()
analysis_df.rename(columns={'影片名称_清理后': '影片'}, inplace=True)
analysis_df = analysis_df.sort_values(by='票房', ascending=False).reset_index(drop=True)
total_seats = analysis_df['座位数'].sum()
total_sessions = analysis_df['场次'].sum()
total_revenue = analysis_df['票房'].sum()
analysis_df['均价'] = np.divide(analysis_df['票房'], analysis_df['人次']).fillna(0)
analysis_df['座次比'] = np.divide(analysis_df['座位数'], total_seats).fillna(0)
analysis_df['场次比'] = np.divide(analysis_df['场次'], total_sessions).fillna(0)
analysis_df['票房比'] = np.divide(analysis_df['票房'], total_revenue).fillna(0)
analysis_df['座次效率'] = np.divide(analysis_df['票房比'], analysis_df['座次比']).fillna(0)
analysis_df['场次效率'] = np.divide(analysis_df['票房比'], analysis_df['场次比']).fillna(0)
final_columns = [
'影片', '座位数', '场次', '票房', '人次', '均价',
'座次比', '场次比', '票房比', '座次效率', '场次效率'
]
analysis_df = analysis_df[final_columns]
return analysis_df
# --- Streamlit 用户界面 ---
st.title('影城排片效率分析工具')
st.write("上传 `影片映出日累计报表.xlsx` 文件。")
uploaded_file = st.file_uploader("请在此处上传 Excel 文件", type=['xlsx', 'xls', 'csv'])
if uploaded_file is not None:
try:
df = pd.read_excel(uploaded_file, skiprows=3, header=None)
df.rename(columns={
0: '影片名称', 2: '放映时间', 5: '总人次', 6: '总收入', 7: '座位数'
}, inplace=True)
required_cols = ['影片名称', '放映时间', '座位数', '总收入', '总人次']
df = df[required_cols]
df.dropna(subset=['影片名称', '放映时间'], inplace=True)
for col in ['座位数', '总收入', '总人次']:
df[col] = pd.to_numeric(df[col], errors='coerce').fillna(0)
df['放映时间'] = pd.to_datetime(df['放映时间'], format='%H:%M:%S', errors='coerce').dt.time
df.dropna(subset=['放映时间'], inplace=True)
df['影片名称_清理后'] = df['影片名称'].apply(clean_movie_title)
st.toast("文件上传成功,数据已按规则处理!", icon="🎉")
format_config = {
'座位数': '{:,.0f}', '场次': '{:,.0f}', '人次': '{:,.0f}',
'票房': '{:,.2f}', '均价': '{:.2f}', '座次比': '{:.2%}', '场次比': '{:.2%}',
'票房比': '{:.2%}', '座次效率': '{:.2f}', '场次效率': '{:.2f}',
}
# --- 1. 全天数据分析 ---
st.header("全天排片效率分析")
full_day_analysis = process_and_analyze_data(df.copy())
if not full_day_analysis.empty:
table_height = (len(full_day_analysis) + 1) * 35 + 3
st.dataframe(
full_day_analysis.style.format(format_config).apply(style_efficiency, axis=1).hide(axis="index"),
height=table_height,
use_container_width=True,
hide_index=True
)
else:
st.warning("全天数据不足,无法生成分析报告。")
# --- 2. 黄金时段数据分析 ---
st.header("黄金时段排片效率分析 (14:00-21:00)")
start_time = pd.to_datetime('14:00:00').time()
end_time = pd.to_datetime('21:00:00').time()
prime_time_df = df[df['放映时间'].between(start_time, end_time)]
prime_time_analysis = process_and_analyze_data(prime_time_df.copy())
if not prime_time_analysis.empty:
table_height_prime = (len(prime_time_analysis) + 1) * 35 + 3
st.dataframe(
prime_time_analysis.style.format(format_config).apply(style_efficiency, axis=1).hide(axis="index"),
height=table_height_prime,
use_container_width=True,
hide_index = True
)
else:
st.warning("黄金时段内没有有效场次数据,无法生成分析报告。")
# --- 3. 一键复制影片列表 ---
if not full_day_analysis.empty:
st.header("复制当日影片列表")
movie_titles = full_day_analysis['影片'].tolist()
formatted_titles = ''.join([f'《{title}》' for title in movie_titles])
st.code(formatted_titles, language='text')
except Exception as e:
st.error(f"处理文件时出错: {e}")
st.warning("请确保上传的文件是'影片映出日累计报表.xlsx',并且格式正确。")
else:
st.info("请上传文件以开始分析。") |