Python什么都知道之手机电池的秘密
手机已经渐渐进化成了人们身体的一部分,手机电量也就跟着成了大家的声明指数(笑)。你是不是觉得夏天的电池比冬天耐用?为什么容量大的电池还是感觉不够?今天就来用Python告诉你,手机电量藏着的小秘密。(华为ICT学堂大数据学院倾情奉献~ https://www.ictxuetang.com/)
首先,我们需要获取一个数据集,然后使用Python中的数据分析包和可视化工具,对手机电池数据进行基本分析。这个数据集主要包含:电池指定时刻的状态信息(Status),包括电池的健康状态(Health)、电池当前的含电量(Level)、含电量度量方式(Scale):百分数、接入状态(Plugged)、电池容量(Voltage)和电池温度(Temperature)。我们也主要分析这些变量间的关系,话不多说,让我们开始吧。
步骤1:加载包
这里首先是加载数据分析所需要使用的数值计算包和可视化工具包,代码如下:
from mpl_toolkits.mplot3d import Axes3D
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt # plotting
import numpy as np # linear algebra
import os # accessing directory structure
mport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
步骤2:读取数据
for dirname, _, filenames in os.walk('D:\workspace\online\phone-battery'):
for filename in filenames:
print(os.path.join(dirname, filename))
输出如下结果:
步骤3:定义数据分布函数
定义数据分布函数,主要用于查看各属性的数据分布,了解各属性的取值特征,并通过直方图实现可视化展示。这样我们可以清楚数据集里的各个值的情况,以确定分析思路和确认数据集是否需要清除冗余字段等操作。
# Distribution graphs (histogram/bar graph) of column data
def plotPerColumnDistribution(df, nGraphShown, nGraphPerRow):
nunique = df.nunique()
df = df[[col for col in df if nunique[col] > 1 and nunique[col] < 50]] # For displaying purposes, pick columns that have between 1 and 50 unique values
nRow, nCol = df.shape
columnNames = list(df)
nGraphRow = (nCol + nGraphPerRow - 1) / nGraphPerRow
plt.figure(num = None, figsize = (6 * nGraphPerRow, 8 * nGraphRow), dpi = 80, facecolor = 'w', edgecolor = 'k')
for i in range(min(nCol, nGraphShown)):
plt.subplot(nGraphRow, nGraphPerRow, i + 1)
columnDf = df.iloc[:, i]
if (not np.issubdtype(type(columnDf.iloc[0]), np.number)):
valueCounts = columnDf.value_counts()
valueCounts.plot.bar()
else:
columnDf.hist()
plt.ylabel('counts')
plt.xticks(rotation = 90)
plt.title(f'{columnNames[i]} (column {i})')
plt.tight_layout(pad = 1.0, w_pad = 1.0, h_pad = 1.0)
plt.show()
步骤4:定义相关性混淆矩阵
定义相关性混淆矩阵,这一步主要是为了用于查看各属性之间的相关性,并通过相关系数热力图实现可视化展示。
ICT学堂大数据课程 https://www.ictxuetang.com/
# Correlation matrix
def plotCorrelationMatrix(df, graphWidth):
filename = df.dataframeName
df = df.dropna('columns') # drop columns with NaN
df = df[[col for col in df if df[col].nunique() > 1]] # keep columns where there are more than 1 unique values
if df.shape[1] < 2:
print(f'No correlation plots shown: The number of non-NaN or constant columns ({df.shape[1]}) is less than 2')
return
corr = df.corr()
plt.figure(num=None, figsize=(graphWidth, graphWidth), dpi=80, facecolor='w', edgecolor='k')
corrMat = plt.matshow(corr, fignum = 1)
plt.xticks(range(len(corr.columns)), corr.columns, rotation=90)
plt.yticks(range(len(corr.columns)), corr.columns)
plt.gca().xaxis.tick_bottom()
plt.colorbar(corrMat)
plt.title(f'Correlation Matrix for {filename}', fontsize=15)
plt.show()
步骤5:定义散点矩阵图
接下来我们定义不同矩阵的散点相关性系数图,用来查看不同属性的散点图和相关系数图,分布电池状态指标之间的关系。
# Scatter and density plots
def plotScatterMatrix(df, plotSize, textSize):
df = df.select_dtypes(include =[np.number]) # keep only numerical columns
# Remove rows and columns that would lead to df being singular
df = df.dropna('columns')
df = df[[col for col in df if df[col].nunique() > 1]] # keep columns where there are more than 1 unique values
columnNames = list(df)
if len(columnNames) > 10: # reduce the number of columns for matrix inversion of kernel density plots
columnNames = columnNames[:10]
df = df[columnNames]
ax = pd.plotting.scatter_matrix(df, alpha=0.75, figsize=[plotSize, plotSize], diagonal='kde')
corrs = df.corr().values
for i, j in zip(*plt.np.triu_indices_from(ax, k = 1)):
ax[i, j].annotate('Corr. coef = %.3f' % corrs[i, j], (0.8, 0.2), xycoords='axes fraction', ha='center', va='center', size=textSize)
plt.suptitle('Scatter and Density Plot')
plt.show()
步骤6:读取2019-11-07的数据
我们选取一天的数据,选择2019-11-07的数据,查看一下数据大小和属性数量。
学ICT课程,就上华为ICT学堂 https://www.ictxuetang.com/
nRowsRead = 1000 # specify 'None' if want to read whole file
# 2019-11-07.csv may have more rows in reality, but we are only loading/previewing the first 1000 rows
df1 = pd.read_csv('D:\\workspace\\online\\phone-battery\\2019-11-07.csv', delimiter=',', nrows = nRowsRead)
df1.dataframeName = '2019-11-07.csv'
nRow, nCol = df1.shape
print(f'There are {nRow} rows and {nCol} columns')
步骤7:查看数据信息
(1)执行如下代码,查看数据的前5行记录。观察一下整理好的数据大概是什么情况,代码和结果如下:
df1.head()
(2)执行如下代码,查看数据的后5行记录。同样观察一下整理好的数据大概是什么情况,代码和结果如下:
df1.tail()
从记录中可以看出,数据是由近到远的。数据中主要记录了电池指定时刻的状态信息(Status),如;电池的健康状态(Health);电池当前的含电量(Level);含电量度量方式(Scale):百分数;接入状态(Plugged); 电池容量(Voltage)和电池温度(Temperature)。好了,明确了数据集的内容,我们接下来需要开始分析各个属性之间的关联性了,看好了别眨眼。
步骤8:查看数据属性取值信息
执行如下命令,调用步骤三定义的函数分析离散属性的取值特征。我们这一步的主要目的是通过直方图的方式统计每个离散属性各值的出现次数。
plotPerColumnDistribution(df1, 10, 5)
从输出结果可以看出,电池的状态主要包括三种,分别是:Discharging,charging,Notcharging。电池的接入状态主要有两种情况一个是None,一个是AC。电池的温度的变化范围28~42度,且最多的时候是集中在33度左右,其次就是41度。也就是说,我们的电池会出于放电、充电和未充电三个转台,电池的温度在28-42之间变化,通常处于33度。
步骤9:查看分析连续属性之间的相关性
plotCorrelationMatrix(df1, 8)
从图中可以看出,当前含电量与电池容量之间呈现很强的正相关性,确实容量大的电池当前电量会大,所以卖手机的没骗你哦;而温度与容量呈现一定较弱的正相关性,温度确实会影响容量,冬季手机温度下降时,电池容量也会相应降低,可用时长也会下降,只是这个影响没有特别大。
步骤10:通过散点图查看三者之间的关系
执行如下代码,通过散点图分析查看温度、电量和电池容量三者之间取值的关系
plotScatterMatrix(df1, 12, 10)
从图中可以看出,对角线上反映的是记录的时间段内,电池电量、容量和温度的分布。结合之前分析,前面也提到数据集主要是记录由近及远不同时刻电池的状态信息,即下午到晚上的手机电池的信息。下午时刻随着温度的升高,电池容量会增加,电池的含电量会下降,当晚上的时候随着温度的降低,电池容量会因手机充电而增加,但是充电结束后也会出现一定程度的下降,而含电量也会呈现类似的变化趋势。
这可以说,边充边玩并没有影响电池容量和电量,而且晚上充电比较快,你学会了嘛?当然了,下午的手机电容量上升,但是电量下降了,emm~2019年11月7日还是个工作日,你肯定又摸鱼玩手机了,来人啊放老板!
总结
从可视化的结果来看,容量与含电量总是存在比较强的正相关关系,而温度与容量和含电量的关系不是特别稳定。但是大多时候,温度较高时电池的容量都会有所增加,手机的使用时长也会相应增加;当温度较低时电池容量和含电量会下降,会影响手机的使用时长,冬天记得给手机保暖哦~
好了,你的手机里的秘密,我们分析出来了,Python改变世界,Python大法好,这么好的东西,我们要在哪里学习呢?ICT学堂数据分析短训营来了,面向0基础学员,基于数据分析挖掘通用能力模型,围绕华为手机真实业务场景,打造6大分析挖掘实战项目,解决学习过程中缺项目无业务场景的痛点。点击链接马上报名吧!(点击立刻报名)学会了,你就能知道你对象手机里的小秘密哦,一般人我不告诉他!欢迎关注 ICT学堂 https://www.ictxuetang.com/
本文地址:https://blog.csdn.net/weixin_40969053/article/details/107243805