介绍
本项目跟踪了某晶体硅太阳能电池车间在2020年3月18日某生产车间一天内所有产生的电池,共计29323个产品的性能测试情况的汇总。可以看到电池效率控制在较好的状态,而影响效率的最主要因素的串联电阻Rs。如果能有办法下降电池片的Rs,就能稳定提高电池片的转换效率。

查看数据的基本情况

import pandas as pd
import matplotlib.pyplot as plt
from dateutil.parser import parse
from pandas.plotting import scatter_matrix  path = r"D:\python\course\Kaikeba\project\XeLamp\dataXe\solarCellData02.xlsx"
data = pd.read_excel(path)
print(data.head())

5 rows × 25 columns

print(data.shape)

(29323, 25)

可以看到该数据由29323行,25列构成。
我们观察到这个数据的第三列"TestTimeDate"相当于第一列和第二列字符串的拼接,因此,这里出现重复信息,我们决定把第一列和第二列删除。接着我们发现最后两列"CellArea"和"Comment"提供的都是始终相同的信息,电池面积和工艺代号。于是我们决定将这2列也删除。

# 删除数据集中对统计无意义的列
data.drop(["TestDate", "TestTime", "CellArea", "Comment"], axis=1, inplace=True)
data.head() 

这样数据集中这4列就没有了。

print(data.info())


我们可以看到数据集中没有NULL值。可是打开原始文件Excel表格后,我们却发现大量0值。我们先统计一下这个情况。

# 统计列中零值的个数
print((data==0).astype(int).sum(axis=0))


我们知道这些等于0的统计条目代表了测试异常。这些值是可以删除的。我们用如下代码删除这些行。

data = data[(data["Bin"] != 0) & (data["IRev2"] != 0) & (data["FF"] != 0)(data["IRev1"] != 0) & (data["OpticalFrontColor"] != 0) &
(data["OpticalFrontQual"] != 0) & (data["OpticalRearQual"] != 0)]  # 统计列中零值的个数
print((data==0).astype(int).sum(axis=0))

# 可以看到有89条数据记录被删除
print(data.shape)

可以看到89条没有意义的数据已经被删除了。

data[["Eta", "Uoc", "Isc", "Rs", "Rshunt", "FF", "Insol", "Pmpp", "Tmonicell"]].hist(bins=50, figsize=(20,15))
plt.show() 

然后我们将和太阳能电池性能高度相关的9个参数绘制成直方图,bin的数量选择50.

可以看到大部分图的横轴都跨度很大,这导致无法细致看清楚直方图内部的细节。这是测试过程中极少量的离群值(outlier)造成的。根据正态分布理论,我们写一个函数,过滤掉3倍标准差以上的离群值。

我们在同一个文件夹下新建一个python文件,取名outlierFilter.py. 然后输入如下代码。

import pandas as pd  # 根据正态分布的特性,可以将3*STD之外的数据视为异常值。
def outlierFilter(data, col):mean, std = data[col].mean(), data[col].std() lower, upper = mean - 3 * std, mean + 3 * stdreturn data[col][(data[col]>lower) & (data[col]<upper)]

然后在主程序中导入该模块。我们对关心的9个特征调用outlierFilter()函数,将离群值过滤掉,再次绘制直方图。其他参数和第一次绘制一样。

from outlierFilter import outlierFilter columnNames = ["Eta", "Uoc", "Isc", "Rs", "Rshunt", "FF", "Insol", "Pmpp", "Tmonicell"]
for element in columnNames:data[element] = outlierFilter(data, element)
data[["Eta", "Uoc", "Isc", "Rs", "Rshunt", "FF", "Insol", "Pmpp", "Tmonicell"]].hist(bins=50, figsize=(20,15))
plt.show()


经过outlierFilter()函数过滤后,数据的分布变得更集中了。我们可以观察到器件的效率Eta分布存在左偏现象,而Rshunt的分布则存在右偏现象。而测试设备的辐照强度的平均值大约在999,这比行业标准低了1个点。因此,这台设备的光源需要进行校正。另外,标准测试的时候要求的温度为25摄氏度,而从图上看出来Tmonicell的平均温度大约在26.0附近。因此,这个参数也需要进行重新校正。

在太阳能电池性能分析中我们通常会重点关注Eta,FF,Uoc,Jsc这四个参数。因此,我们可以绘制一个scatter_matrix矩阵来进行观察。

from pandas.plotting import scatter_matrix attributes = ["Eta", "FF", "Jsc", "Uoc"]
scatter_matrix(data[attributes], figsize=(12, 8), alpha=0.1)
plt.show() 


从图中可以看到FF和Uoc与器件效率的正相关还是很明显的。我们再详细地观察一下这2个图。

data.plot(kind="scatter", x="FF", y="Eta", color="r", alpha=0.1)
data.plot(kind="scatter", x="Uoc", y="Eta", color="g", alpha=0.1)
plt.show()

从这两张scatter图上可以看到FF,Uoc和Eta之间均存在正相关性。

我们知道通常Rs和Rshunt会影响太阳能电池的FF。因此,我们再绘制两张对应的scatter图。从这两张图我们能看到:FF受Rs的影响更敏感,而不太会受到Rshunt的影响。而FF和Rs之间是一种负相关性。因此,将Rs控制在0.002以下,能有效提升FF,从而提升器件的效率。

data.plot(kind="scatter", x="Rs", y="FF", color="r", alpha=0.1)
data.plot(kind="scatter", x="Rshunt", y="FF", color="g", alpha=0.1)
plt.show() 


受到上方左侧FFvs. Rs图像的启发,为了进一步分析Rs对器件性能的影响,我们编写一个叫seriesRranking的函数(含义是series resistance ranking, 就是对串联电阻进行排序)。 然后在主程序中导入该模块,对原始数据调用该函数后可以发现:Rs能够小于0.0018的一共只有8个。而最多的是介于[0.002, 0.0022]之间的器件,多达19409个。

# 编写函数,将Rs转换为对应等级
def seriesRranking(Rs):if Rs >= 0 and Rs < 0.0018:return "一级"elif Rs >= 0.0018 and Rs < 0.002:return "二级"elif Rs >= 0.002 and Rs < 0.0022:return "三级"elif Rs >= 0.0022 and Rs < 0.0024:  return "四级"elif Rs >= 0.0024 and Rs < 0.0026:return "五级" else: return "六级"
import seaborn as sns
from seriesRranking import seriesRranking sns.set(style="darkgrid")
plt.rcParams["font.family"] = "SimHei"
plt.rcParams["axes.unicode_minus"] = False
level = data["Rs"].apply(seriesRranking)
print(level.value_counts())
sns.countplot(x=level, order=["一级", "二级", "三级", "四级", "五级", "六级"])
plt.show() 



然后我们在该DataFrame的尾部在再插入一个新列,该列使用seriesRranking函数对Rs进行分类贴签。然后我们使用seaborn.scatterplot()绘图函数绘制一个下面这样的散点图。由于总数据量太多,我们从中截取了ID排序最后的1500个数据点。可以看到:图像下方的圆点主要集中于五级和六级,而图像上方的点则以三级和四级为主。这说明Rs在这里显著影响了器件效率的分布。而三级和四级的点在有不少在图像下方和五级六级的点混杂在了一起,这说明影响器件效率的因素绝非Rs一个。

data["RsRanking"] = data["Rs"].apply(seriesRranking)
data = data.sort_values(by="ID", ascending=True)
dataPiece = data.iloc[-1500 :]
sns.scatterplot(x="ID", y="Eta", hue="RsRanking", data=dataPiece)
plt.show() 


器件外观对效率的影响
为了研究器件外观对效率的影响,我们绘制Eta/OpticalFrontColor的Violinplot。可以看到效率分布的峰值随着器件表面颜色的分类号上升。我们知道器件正面减反射膜的厚度会同时影响器件的外观和电流。

pal = sns.cubehelix_palette(4, rot=-0.5, dark=0.3)
sns.violinplot(x="OpticalFrontColor", y="Eta", data=data, palette=pal, inner="points")
plt.show() 


因此我们又绘制出了Jsc/OpticalFrontColor和Uoc/OpticalFrontColor的Violinplot。这次我们可以看到Jsc的分布峰值和Eta的分布类似,而Uoc的分布峰值则和Eta的分布相反。这就验证了器件外观会影响到Jsc参数,进而影响器件的效率的假设。

data["Jsc"] = outlierFilter(data, "Jsc")
pal = sns.cubehelix_palette(4, rot=-0.5, dark=0.3)
sns.violinplot(x="OpticalFrontColor", y="Jsc", data=data, palette=pal, inner="points")
plt.show() 
data["Uoc"] = outlierFilter(data, "Uoc")
pal = sns.cubehelix_palette(4, rot=-0.5, dark=0.3)
sns.violinplot(x="OpticalFrontColor", y="Uoc", data=data, palette=pal, inner="points")
plt.show() 


检查工序连贯性
有些时候,为了整体把握一条产线各道工序的连贯性,我们会将同一时期生产器件的效率进行排序后,将log(Eta)做纵轴,排序后的序列号做横轴绘制一个半对数曲线。我们可以用这种技术查看一下这条产线的工艺连贯程度。

data["Eta"] = outlierFilter(data, "Eta")
efficiency = data["Eta"].values.tolist()
efficiency.sort()
array = [i for i in range(len(efficiency))]
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
plt.semilogy(array, efficiency, "o", ms=3, mew=2.5, mec='navy')
plt.title("电池效率的半对数图")
plt.show()


可以看到整条曲线非常连贯,中间没有不连续的区域。这说明,整条产线的工艺控制非常好,没有出现明显的影响器件性能的工艺缺陷。否则,这条曲线会出现不连续的情况。曲线在头部和尾部出现和y轴近似平行的现象(红色虚线圈区域)说明效率分布在这个区域的器件非常少。我们也发现,最高的一片电池的效率约为22.9%,这个数值远远高于排名第二的器件。这基本可以归因于和产线工艺无关的因素,例如硅片自身的质量。

对时间序列的处理

# 使用dateutil.parser.parse() 函数将机器产生的表示时间的字符串转
# 换为datetime.datetime格式
from dateutil.parser import parse
data['TestTimeDate'] = data['TestTimeDate'].iloc[:].apply(parse)
data = data.reset_index()
print(data[["TestTimeDate", "ID", "Bin", "Eta", "Uoc", "Jsc", "FF"]].head())


我们看到dateutil模块下的parser.parse()函数已经将TestTimeDate转换成时间序列格式。保险起见,我们再查看该列的数据类型。

print(data["TestTimeDate"].dtype) 


然后我们对数据再一次调用outlierFilter函数,希望能将3*STD以外的数据过滤掉。经过这个步骤后,我们将8个最关心的特征(分别是TestTimeDate, ID, Eta, Uoc, Jsc, FF, Rs, Rshunt)建立一个新的DataFrame, 然后查看数据中的NULL值,发现还是有大量的缺省值。因此,我们在这里调用data.dropna()函数,将任意包括NULL值的行都删除掉。然后,我们再查看的时候,发现8个特征里面已经没有NULL值了。而总数据条目变成了28382行。

print(data.isnull().sum(axis=0))
data.dropna(axis=0, how='any', inplace=True)
data = data.reset_index(drop=True)
print(data.isnull().sum(axis=0))
print(data.shape)


然后我们根据向下采样的概念(就是将DataFrame从一个较高的时间频率切换到一个较低的时间频率),将数据按小时进行聚合,并计算每个小时内Eta,Jsc,Uoc,FF的平均值。然后绘制成散点图。

def scatterPlot(xcol, ycol, xlabel, ylabel):ts = pd.Series(data[ycol].values, index=data[xcol])    resample = ts.resample('60T', closed='right').mean()     x = resample.index.tolist()y = resample.values.tolist() plt.figure(figsize=(11, 6)) font1 = {'family':'Consolas','weight':'light','size':22} plt.scatter(x, y, marker='o', color='r', s=35)  array = ["8:00", "9:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00", "17:00", "18:00", "19:00", "20:00"] plt.xticks(x, array) plt.xticks(fontsize=16) plt.yticks(fontsize=18) plt.xlabel(xlabel, font1)plt.ylabel(ylabel, font1)  plt.show()
scatterPlot("TestTimeDate", "FF", "Time", "FF")

下面这个结果是对ts这个pd.Series调用取样函数resample()后的运算结果。

下面是对四种关键电池参数按小时进行聚合后取平均值绘制的散点图。我们可以看到首先在这个班次的数据中,Eta先经历了一个大约4h的上升期,然后开始迅速下降。其次三个直接影响电池效率的参数中,只有Jsc和Eta的趋势是完全一致的。而其他两个参数的趋势正好相反,这让他们对器件效率的影响最终互相抵消掉了。

绘制箱线图

最后我们想看一下箱线图沿该产线以小时为单位的聚合数据的统计分布。我们先定义一个函数toHour()。该函数能将DataFrame中格式为TimeStamp的时间序列转换为字符串形式。然后我们从字符串中提取小时(hour)对应的切片,放置在新建的列”Hour”中。做好了这些准备工作,就可以使用seaborn.boxplot()函数进行绘图了。我们依次绘制四个关键参数的箱线图。可以发现整体趋势和上面的散点图基本一致。而Eta和FF在最后一列的分布明显更窄。这是近邻收工时所采集的样本集变小造成的。

def toHour(element):local_time = pd.to_datetime(element)dt = str(local_time)[11:13] return dt    data["Hour"] = data["TestTimeDate"].apply(toHour)
plt.figure(figsize=(8,6))
sns.set(style="darkgrid")
sns.boxplot(x='Hour', y='Jsc', data=data)
plt.xlabel('Hour', {'size':20})
plt.ylabel('Jsc', {'size':20})
plt.xticks(fontsize=18)
plt.yticks(fontsize=18)
plt.show()

晶体硅太阳能电池产线性能跟踪项目相关推荐

  1. 《华林科纳-半导体工艺》高效硅太阳能电池

    引言 硅仍然是光伏的首选材料,因为它丰富.无毒.电池效率高且稳定.生产基础设施成熟,而且硅器件的技术水平深厚且广泛.模块价格的快速下降意味着与面积相关的系统成本平衡在光伏系统价格中所占比例越来越大.这 ...

  2. 隔空作画,握拳清屏,这个手部跟踪项目火了,在线可玩

    在屏幕上隔空作画是近来新兴的一种有趣应用,其中涉及复杂的手部跟踪技术,这类技术成熟之后可用于提升应用程序的交互体验.此前机器之心曾报道过可以隔空写字.绘图的有趣项目「air-drawing」,该项目利 ...

  3. 使用最新目标跟踪框mmtracking实现自己的目标跟踪项目

    文章目录: 1 搭建环境 2 mmtracking目标跟踪框及原理介绍 之前也一直在关注目标跟踪方面的项目,尤其是多目标跟踪,目前比较主流的多目标跟踪都是基于deepsort来做的,这方面开源的研究工 ...

  4. 项目工作任务 excel_在Excel中跟踪项目任务

    项目工作任务 excel If you're working on an Excel project with a client, or other employees in your company ...

  5. 计算机芯片材料晶体硅,硅晶片

    元素硅是一种灰色.易碎.四价的非金属化学元素.地壳成分中27.8%是硅元素构成的,仅次于氧元素含量排行第二,硅是自然界中比较富的元素.在石英.玛瑙.燧石和普通的滩石中就可以发现硅元素.硅晶片又称晶圆片 ...

  6. 线性表【项目 - 求集合并集C语言】(带注释)

    #include <stdio.h> #define MAXSIZE 50 //您也可以使用 typedef 来为用户自定义的数据类型取一个新的名字.例如,您可以对结构体使用 typede ...

  7. 线性表【项目 - 求集合并集C语言】

    #include <stdio.h> #define MAXSIZE 50 //您也可以使用 typedef 来为用户自定义的数据类型取一个新的名字.例如,您可以对结构体使用 typede ...

  8. 目标跟踪项目 问题及解决方法记录

    移植了Autoware-AI perception中的lidar_kf_contour_track包,移植过程中遇到很多问题,最后一一解决了. lidar_kf_contour_trackhttps: ...

  9. 《炬丰科技-半导体工艺》 硅蚀刻及其在太阳能电池制造过程中的应用

    书籍:<华林科纳-半导体工艺> 文章:硅蚀刻及其在太阳能电池制造过程中的应用 编号:JFKJ-21-1108 作者:华林科纳 引言 随着对世界能源环境问题的关注增加,对可再生能源太阳能发电 ...

最新文章

  1. Android中Broadcast
  2. oracle对日期date类型操作的函数
  3. Oracle编程入门经典 第9章 掌握SQL*Plus
  4. 表的插入、更新、删除、合并操作_3_插入新的多条记录
  5. 全Sql语句实现SBO事务日志记录与查询
  6. android intent 跳转activity,Activity 跳转 都知道用startActivity(Intent)
  7. 谷歌EfficientNet缩放模型,PyTorch实现出炉,登上GitHub热榜丨Demo可用
  8. 数据结构简答题和论述题
  9. VS2013编译提示无法运行“rc.exe”错误
  10. protobuf 编码实现解析(java)
  11. Pytroch+DGL+模型设置相关总结
  12. v21 v8中资源找不到
  13. 第九部分 项目沟通管理
  14. vulhub学习(1) ActiveMQ反序列化漏洞(CVE-2015-5254)复现
  15. Windows10查看本机连接过的WiFi密码
  16. python基础趣讲精练_Python内置函数精讲精练 enumerate()
  17. java 连接池配置_【Java】java数据库连接池配置的几种方法
  18. QMC5883L与msp430FG4618--IIC通信
  19. linux修改配置文件configure,./configure 的配置和用法
  20. 计算机网络--错题集

热门文章

  1. world标题是大写数字,题注要阿拉伯数字,交叉引用不会出错
  2. python解释器环境中用于表示上一次运算结果的特殊变量_Python语句print(type(1//2))的输出结果是...
  3. PS出现“不能完成存储为命令,因为没有足够的内存RAM” 设置性能时“要求96和8之间的整数。已插入最接近的数值”
  4. 泛微文书定确保电子档案移交接收过程:真实、完整、可用和安全
  5. Shell编程之第二讲——shell 的变量
  6. Shopee使用虚拟信用卡绑卡测试购物教程
  7. 【Havel 定理】Degree Sequence of Graph G
  8. 关于markdown图片显示
  9. Outlook邮件撤回有时间限制吗_怎么操作?
  10. python函数可以分为哪几类_python函数有哪几种