目录
一,前言:
新能源汽车行业涉及大量数据,包括销售数据、充电设施数据、车辆性能数据等。利用Python进行数据分析和可视化可以帮助企业更好地理解市场趋势、用户需求和产品表现,为决策提供有力支持。
Python可以编写自动化脚本,从不同数据源获取数据并生成报告,节省人力和时间成本。这对于需要定期生成报告的企业来说尤其重要,可以保持报告的及时性和准确性。
新能源汽车行业处于快速发展阶段,技术和创新是竞争的关键。利用Python进行报告生成不仅能提高工作效率,还可以通过引入新的分析方法和工具不断优化报告内容和质量,保持企业在行业中的竞争优势。
二,报告的效果展示
车辆状态
三,python生成pdf报告的实现过程
1,清洗can信号数据
#整车零部件状态
df2 = pd.DataFrame()
df2['DPB激活'] = np.where(df_func['IDB7_DynParkBrkByIDBActive'.lower()] == 1, 1, 0)
df2['ABS激活'] = np.where(df_func['IDB7_ABSActive'.lower()] == 1, 1, 0)
df2['TCS激活'] = np.where(df_func['IDB7_TCSActive'.lower()] == 1, 1, 0)
df2['ESC激活'] = np.where(df_func['IDB7_ESCActive'.lower()] == 1, 1, 0)
df2['ARP激活'] = np.where(df_func['IDB7_ROPACTIVE'.lower()] == 1, 1, 0)
print("================22222========================")
# df2['AVH激活'] = np.where(df_func['IDB7_AVHStatus'.lower()] == 1, 1, 0)
print("================3333========================")
df2['EPB激活'] = np.where(df_func['IDB6_EPBStatus'.lower()].isin([2, 3, 4, 5]), 1, 0)
print("================4444========================")
df2['HDC激活'] = np.where(df_func['IDB7_HDCAtive'.lower()] == 1, 1, 0)
print("================22222========================")
df2['ABS故障'] = np.where(df_func['IDB7_ABSFail'.lower()] == 1, 1, 0)
df2['EBD故障'] = np.where(df_func['IDB7_EBD_Fail'.lower()] == 1, 1, 0)
df2['TCS故障'] = np.where(df_func['IDB7_TCSFail'.lower()] == 1, 1, 0)
df2['ESC故障'] = np.where(df_func['IDB7_ESCFail'.lower()] == 1, 1, 0)
df2['ARP故障'] = np.where(df_func['IDB7_ROPFailure'.lower()] == 1, 1, 0)
print("================22222========================")
df2['ESC处于关闭状态'] = np.where(df_func['IDB7_TCSDisable'.lower()] == 1, 1, 0)
df2['制动盘温度过高'] = np.where(df_func['IDB5_BrakeDiscTempSts'.lower()] == 1, 1, 0)
df2['刹车踏板信号无效'] = np.where(df_func['IDB1_BrakePedalAppliedV'.lower()] == 0, 1, 0)
df2['档位信号无效'] = np.where(df_func['VCU5_ActGearValid'.lower()] == 0, 1, 0)
df2['油门踏板信号无效'] = np.where(df_func['VCU5_AccelPositionValid'.lower()] == 0, 1, 0)
df2['加速度信号无效'] = np.where((df_func['ACU2_LatAccSensorValueV'.lower()] == 0) |
(df_func['ACU2_VehicleDynYawRateV'.lower()] == 0) |
(df_func['ACU2_LongAccSensorValueV'.lower()] == 0), 1, 0)
df2['车速信号无效'] = np.where(df_func['IDB3_VehicleSpdValid'.lower()] == 0, 1, 0)
df2['车辆静止信号无效'] = np.where(df_func['IDB5_VehicleStanstill'.lower()] == 2, 1, 0)
df2['电子档位杆无效'] = np.where(df_func['CS1_GearPositionReqStValid'.lower()] == 0, 1, 0)
df2['方向盘信号无效'] = np.where(df_func['EPS1_SteeringAngleValid'.lower()] == 0, 1, 0)
df2['左方控ACC按键无效'] = np.where(df_func['Region_A_SwError'.lower()] == 1, 1, 0)
df2['轮速信号无效'] = np.where((df_func['IDB4_FLWhlVelocityValid'.lower()] == 0) |
(df_func['IDB4_FRWhlVelocityValid'.lower()] == 0) |
(df_func['IDB4_RRWhlVelocityValid'.lower()] == 0) |
(df_func['IDB4_RLWhlVelocityValid'.lower()] == 0), 1, 0)
print("========================================")
df2['四门两盖任一处于开启状态'] = np.where(
(df_func['BDCS1_HoodAjarSts'.lower()] == 1) | (df_func['BDCS1_TrunkLockSts'.lower()] == 0) |(df_func['DDCU1_FLDoorAjar'.lower()] == 2) | (df_func['DDCU1_RLDoorAjar'.lower()] == 2) |(df_func['PDCU1_FRDoorAjar'.lower()] == 2) | (df_func['PDCU1_RRDoorAjar'.lower()] == 2), 1, 0)
df2['双闪开启'] = np.where(df_func['BDCS1_HazardLampSt'.lower()] == 1, 1, 0)
df2['EPS未标定'] = np.where(df_func['EPS1_HSTWCalibrated'.lower()] == 0, 1, 0)
df2['动力系统ACC扭矩未ready'] = np.where(df_func['VCU14_ACC_Ready'.lower()] == 0, 1, 0)
df2['IDB不支持ACC功能'] = np.where(df_func['IDB5_ACC_Enable'.lower()] != 0, 1, 0)
print("========================================")
df = df.reset_index(drop=False)
df2 = df2.reset_index(drop=False)
df = pd.concat([df, df2], axis=1)
print("df....")
print(df.columns)
2,清洗车道线数据
try:
df_lane['send_time'] = pd.to_datetime(df_lane['timestamp'], unit='ms').astype(str)
df_cat = df_lane[~((df_lane['lane1_linemarkcolor'] == 0) & (df_lane['lane1_type'] == 0) & (df_lane['lane1_status'] == 0))][
['send_time', 'lane1_curvature']]
print("df_cat:")
print(df_cat)
df = df_lane[['timestamp']].astype('str')
df['send_time'] = pd.to_datetime(df_lane['timestamp'], unit='ms').astype(str)
df['大曲率弯路'] = df_cat['lane1_curvature'] > 0.005
df1 = df.groupby('send_time')['大曲率弯路'].apply(list).reset_index()
df1['是否大曲率弯路'] = df1['大曲率弯路'].apply(lambda x: sum(x) > 0)
df1.to_pickle(savepath + 'df_j3_lane_cleaned_' + vehicle_id + '_' + day + '_' + hour + '_' + bagname + '.pkl')
except Exception as e:
print('data cleaning lane error, ', str(e))
3,清洗环境数据(障碍物数据)
df_obj_filtered = df_obj[df_obj['obj_id'] > 0]
df['objCount'] = df_obj_filtered.groupby(pd.Grouper(key='send_time'))['obj_id'].transform('count')
df['objCount']=df['objCount'].fillna(0)
print("df_obj_filtered....")
print(df['objCount'])
df['position'] = (df_obj['obj_px'] ** 2 + df_obj['obj_py'] ** 2).astype(
'float').apply(np.sqrt)
condition_1 = [
df_obj['obj_class'] == 0, df_obj['obj_class'] == 1, df_obj['obj_class'] == 2, df_obj['obj_class'] == 3, df_obj['obj_class'] == 4, df_obj['obj_class'] == 5,
df_obj['obj_class'] == 6, df_obj['obj_class'] == 7, df_obj['obj_class'] == 8
]
# value_1 = [
# '未知', '行人', '自行车', '摩托车', '三轮车', '轿车',
# '卡车', '客车公交', '专用车', 'SUV', 'Minibus', 'Ambulance',
# 'Firetruck', '工程车', 'Animal', '小货车'
# ]
value_1 = [
'未知', '轿车', '摩托车', '客车公交', '小货车', '专用车',
'行人', '自行车', 'Tricycle']
df['type_obj'] = np.select(condition_1, value_1)
4,标签数据清洗
filter_acc_long = signal.lfilter(b, a, df_ego['纵向加速度'])
df_filter_acc_long = pd.DataFrame(filter_acc_long, columns=['filter_acc_long'])
df_ego = pd.concat([df_ego, df_filter_acc_long], axis=1).sort_values('timestamp')
df_ego['lag_filter_acc_long'] = df_ego['filter_acc_long'].shift(1)
df_ego['diff_filter_acc_long'] = df_ego['filter_acc_long'] - df_ego['lag_filter_acc_long']
df_ego['lag_time'] = df_ego['timestamp'].shift(1)
df_ego['diff_time'] = df_ego['timestamp'] - df_ego['lag_time']
df_ego['jerk_longi'] = df_ego['diff_filter_acc_long'] / df_ego['diff_time'] * 1000
df_ego['tap_brake'] = np.where(
(df_ego['jerk_longi'].abs() > 3.65) & (df_ego['filter_acc_long'] < -1.34) & (df_ego['ACC状态'] == 'ACC激活'),
1, 0)
df.loc[0, '点刹'] = np.where(1 in df_ego['tap_brake'].unique(), 1, 0)
df_ego['左变道'] = (df_ego['方向盘转角'] > 20) & (df_ego['车速'] > 15)
df_ego['右变道'] = (df_ego['方向盘转角'] < -20) & (df_ego['车速'] > 15)
df.loc[0, '左变道'] = np.where(any(df_ego['左变道'] == True), 1, 0)
df.loc[0, '右变道'] = np.where(any(df_ego['右变道'] == True), 1, 0)
5,通过matplotlib生成报告需要的图片
def plot_adas(savepath,vehicle_id,day,hour,bagname,df,title,secondary_y =False,annotate=''):
print("11111111111111111111111111111111111111111")
#指定画布
fig1 = plt.figure(figsize=(18,10), tight_layout=True)
#在fig1上添加子图,行数为1,列数为1
ax1 = fig1.add_subplot(1, 1, 1)
# ax1.xaxis.set_major_locator(dates.SecondLocator(interval=1))
#用于指定如何显示 x 轴上的日期时间信息
ax1.xaxis.set_major_formatter(dates.DateFormatter('%H:%M:%S'))
# nan_rows = df[df.isna().any(axis=1)]
# # print(nan_rows)
#kind : 类型为线型的图形
#title: 设置标题
#secondary_y: 这是一个布尔参数,用于指示是否应在图表的右侧创建一个辅助(次要)Y轴。如果设置为True,那么数据将根据右侧的Y轴刻度绘制。
#mark_right: 这是一个布尔参数,用于指示是否应在图表的右侧标记数据。如果设置为False,数据点将不会在右侧的Y轴上标记。
ax1 = df.plot(kind='line', ax=ax1, style='-o', title=title, secondary_y = secondary_y, mark_right=False)
# global trigger_time, vehicle_id, trigger_package
# ax1.axvline(trigger_time, color = 'r', linestyle='--')
# ax1.text(trigger_time[0]+pd.Timedelta(200, unit='ms'), df[df.columns[0]].max(), 'Trigger触发时间点', color = 'red',
# bbox=dict(boxstyle='round,pad=0.3', fc='yellow', ec='k',lw=1 ,alpha=0.5))
print("pilot=====================================")
if secondary_y != False and secondary_y != '转向手力矩':
#用于设置Y轴的标签文本
ax1.set_ylabel(df.columns[0])
#用于设置右侧Y轴的y轴的标签文本。
ax1.right_ax.set_ylabel(df.columns[1])
elif secondary_y != False and secondary_y == '转向手力矩':
ax1.set_ylabel(df.columns[0] + ',' + df.columns[1])
ax1.right_ax.set_ylabel(df.columns[2])
else:
#添加图例
ax1.legend(loc='best')
ax1.set_xlabel(None)
#plt.legend(loc='best')
#网格线将以虚线的形式绘制在图表上,线宽为0.5,颜色为灰色,以帮助视觉上更好地理解图表中的数据点和趋势
ax1.grid(ls='--', lw=0.5, color='#4E616C')
y_min, y_max = ax1.get_ylim()
x_min, x_max = ax1.get_xlim()
if title == '方向盘变化':
ax1.annotate('*根据方向盘转角实际值和请求值的波动频率,可判断是否发生了方向盘抖动。', xy=(x_min, y_min), xytext=(x_min, y_min-(y_max-y_min)/7), fontsize=18, ha='left')
if title == '横摆角速率及加速度变化':
#黄线
# ax1.right_ax.axhline(y=-0.8, color='orange', linestyle='--')
# ax1.right_ax.axhline(y=0.8, color='orange', linestyle='--')
ax1.annotate('*此trigger' + annotate + '(NNP或PILOT处于激活状态、转向灯关闭, 且横向加速度存在2个波峰波谷, 波峰波谷的差值分别大于1和0.6且至少一个幅值大于0.5, 则疑似出现画龙).', xy=(x_min, y_min), xytext=(x_min, y_min - (y_max - y_min) / 7), fontsize=14, ha='left')
plt.savefig(savepath + vehicle_id + '_' + day + '_' + hour + '_' + bagname + '_' + title + '.png', dpi=600, transparent=False)
# plt.show()
6,生成doc报告文件,生成pdf文件
doc=get_main_text(doc, df)
#添加head...
doc=add_head(savepath, doc, vehicle_id, day, hour, bagname)
# 页眉页脚设置
doc=add_header_footer(doc, catalog_p,savepath)
report_name = '智驾相关事故定责分析报告'
doc_name = report_name + '.docx'
pdf_name = report_name + '.pdf'
doc_file = savepath + doc_name
doc.save(savepath + doc_name)
# pdf_file = savepath + pdf_name # 要生成的文件:不存在
pdf_file = savepath
doc_to_pdf(doc_file, pdf_file)
金三银四大数据面试黄金期,想要获取详细大数据面试题,请加入星球。