Python机器学习:使用Pandas进行探索性数据分析 Ⅰ

Python机器学习:使用Pandas进行探索性数据分析 Ⅰ

一、前言

数据分析及其预测,在很多领域中都能用到,本期博客,我们来学习一下使用Pandas库对会计业务的数据分析预测并将其可视化。

会计业务的信息量很大,正常的处理起来非常的耗时间,灵活运用Python中的数据分析工具Pandas可以有效的提高处理效率,不管是学计算机的还是学会计学的都可以来学习一下,将其视为一个方便快捷的工具,可以让你事半功倍。

二、我的环境

  • 电脑系统:Windows 11
  • 语言版本:Python 3.10.4
  • 编译器:DataSpell 2022.2

三、数据理解

我们的数据集是一个CSV文件,我们来查看一下:

import pandas as pd

df = pd.read_csv('regression.csv')
df.head()

在这里插入图片描述

我们可以看出这个CSV文件包含时间,成本中心,账户有关信息以及金额,我们的目标就是最后的金额分析。

以上是返回前五行数据,我们再返回最后五行数据看看:

df.tail()

在这里插入图片描述

从时间上我们可以看出这个CSV文件有总共三年的数据量。

在机器学习中,有一件很重要的事情就是评估数据的质量,我们来查看一下我们的数据有没有任何缺失值:

df.info()

它运行的结果是:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4212 entries, 0 to 4211
Data columns (total 7 columns):
 #   Column               Non-Null Count  Dtype  
---  ------               --------------  -----  
 0   Year                 4212 non-null   int64  
 1   Month                4212 non-null   object 
 2   Cost Centre          4212 non-null   object 
 3   Account              4212 non-null   int64  
 4   Account Description  4212 non-null   object 
 5   Account Type         4212 non-null   object 
 6   Amount               4212 non-null   float64
dtypes: float64(1), int64(2), object(4)
memory usage: 230.5+ KB

通过non-null可以看出我们的数据中的每一个参数都没有出现缺失值,并且我们的数据集中每一个参数下都有4212个值。

接下来我们我们来检查列中值得唯一性,我们可以通过这个检查来了解我们有多少不同类型得类别:

for col in df.columns:
    print(col, len(df[col].unique()), df[col].unique())

它运行的结果是:

Year 3 [2019 2020 2021]
Month 12 ['Jan' 'Feb' 'Mar' 'Apr' 'May' 'Jun' 'Jul' 'Aug' 'Sep' 'Oct' 'Nov' 'Dec']
Cost Centre 9 ['CC100' 'CC101' 'CC102' 'CC200' 'CC201' 'CC202' 'CC300' 'CC301' 'CC302']
Account 13 [1000000 1000001 1000002 1000004 2000000 2000001 2000002 2000003 2000005
 3000000 3000001 3000002 4000001]
Account Description 13 ['Product Sales' 'Licensing Revenue' 'Service Revenue' 'Fee Revenue'
 'Cost of Good Sold' 'Staff Expenses' 'Technology Expenses'
 'Property Expenses' 'Purchases' 'Cash at Bank' 'Inventory'
 'Accounts Receivable' 'Accounts Payable']
Account Type 4 ['Revenue' 'Expense' 'Asset' 'Liability']
Amount 3956 [1344.051  480.968  650.82  ... -282.056  537.478 1152.68 ]

我们可以看出有两列代表相同类型的数据,我们后续可能会删除其中一列数据,所以我们只有四种不同的账户类型:收入、支出、资产和负债。

现在,我们来检查我们的数据分布情况:

df.describe()

在这里插入图片描述

df.types

在这里插入图片描述

四、数据可视化

from matplotlib import pyplot as plt
import seaborn as sns

在这里插入图片描述

如果你在这一步中遇见这样的报错:

AttributeError: module 'numpy.linalg.lapack_lite' has no attribute '_ilp64'

你需要重新下载numpy,我下载的版本是1.19.5,然后重启内核就解决了。

好啦,我们来看一下上面的图,可以看出我们的收入账户倾向于800到900左右,费用也非常的接近,资产略高一点,而负债差异很大,所以我们的交易分布有点分散。区间为900到-1500左右。

我们来专注于看一下负债账户:

plt.figure(figsize=(20,6))
sns.violinplot(x='Account', y='Amount', data=df[df['Account Type']=='Liability']).set_title('Liability ViolinPlot')
plt.show()

在这里插入图片描述

现在我们来看一下收入:

plt.figure(figsize=(20,6))
sns.violinplot(x='Account Description', y='Amount', data=df[df['Account Type']=='Revenue']).set_title('Liability ViolinPlot')
plt.show()

在这里插入图片描述

可以看出收入都平均在900左右。

五、回归趋势

前面我们都在单独的看某一账户,现在我们添加时间进去,查看一下回归趋势,我们将月份转换成对应的月份数字字典方便处理。

monthmap = {
    'Jan':1,
    'Feb':2,
    'Mar':3,
    'Apr':4,
    'May':5,
    'Jun':6,
    'Jul':7,
    'Aug':8,
    'Sep':9,
    'Oct':10,
    'Nov':11,
    'Dec':12,
}
monthmap['Jan']

它运行的过程是:

1

然后循环遍历月份列中的每个值,并应用这个月份的地图转换:

df['Period'] = df['Month'].apply(lambda x: monthmap[x])

我们再次检查我们的数据看看是否转换成功:

df.head()

在这里插入图片描述

可以看出我们已经转换成功了。

再将一天设置成1:

df['Day'] = 1
df.head()

在这里插入图片描述

紧接着将其转换为日期/时间:

df['Date'] = df['Year'].astype(str) + '-' + df['Period'].astype(str) + '-' + df['Day'].astype(str)
df.head()

在这里插入图片描述

我们检查一下数据类型:

df.dtypes

在这里插入图片描述

可以发现日期对象还是一个object对象,我们再转换一下:

df['Date'] = pd.to_datetime(df['Date'])
df.dtypes

在这里插入图片描述

现在转换成了时间日期对象了。

我们先把收入可视化,一般收入比较重要,展示季节性变化:

plt.figure(figsize=(20,6))
sns.lineplot(x='Date', y='Amount', hue='Account Description', estimator=None, data=df[df['Account Type']=='Revenue']).set_title('Seasonal Sales')
plt.show()

在这里插入图片描述

上面就是我们所有的计数可视化图,比较的混乱,我们选择其中一个特定的账户,比如产品销售:

plt.figure(figsize=(20,6))
sns.lineplot(x='Date', y='Amount', hue='Account Description', estimator=None, data=df[df['Account Description']=='Product Sales']).set_title('Seasonal Sales')
plt.show()

在这里插入图片描述

我们再看看服务收入:

plt.figure(figsize=(20,6))
sns.lineplot(x='Date', y='Amount', hue='Account Description', estimator=None, data=df[df['Account Description']=='Service Revenue']).set_title('Seasonal Sales')
plt.show()

在这里插入图片描述

对比发现服务收入没有像产品销售那样具有季节性。

六、账户之间的相关性

想检查账户之间是否存在相关性,必须看看服务收入,可能与员工成本挂钩,我们希望能捕捉到这种关系:

df['Account Description'].unique()

在这里插入图片描述

为每个单独的账户创建列:

pd.get_dummies(df['Account'])

在这里插入图片描述

我们将上面的列添加到之前的数据中,并循环执行转换,然后存储在一个新列表中:

corrdict = {}
for key, row in df.join(pd.get_dummies(df['Account'])).iterrows():
    corrdict[key] = {int(row['Account']):row['Amount']}

紧接着将其转换为数据框,然后计算相关性:

corrdf = pd.DataFrame.from_dict(corrdict).T.fillna(0)
corrdf

在这里插入图片描述

然后计算相关性:

corrdf.corr()

在这里插入图片描述

这个表很难进行可视化,我们尝试一下热图:

plt.figure(figsize=(20,6))
sns.heatmap(corrdf.corr()).set_title('Account Correlation')
plt.show()

在这里插入图片描述

可以发现几乎所有的账户之间都没有很强的相关性。

我们来看看金额3000000账户和金额4000001账户是什么账户:

df[df['Account']==3000000]

在这里插入图片描述

df[df['Account']==4000001]

在这里插入图片描述

七、数据准备

我们来查看每一个账户:

import numpy as np

for account in df['Account'].unique():
    plt.figure(figsize=(20,6))
    sns.lineplot(x='Date', y='Amount', estimator=np.median, hue='Account Description', data=df[df['Account']==account]).set_title('{} by Month'.format(account))
    plt.show()

在这里插入图片描述

通过观察这些图,可以发现有一张图的趋势非常的奇怪,它与其他部分遵循不同的季节性,我们需要将其去掉。

df = df[df['Account']!=3000001]
df['Account'].unique()

在这里插入图片描述

可以看见我们已经除去了那个异常的数据,

八、将字段转换为正确的数据类型

检查一下数据类型

df.dtypes

在这里插入图片描述

确保年份和账户获取正确的数据类型,我们在账户前面添加ACC标识:

df['Account'] = 'ACC' + df['Account'].astype(str)
df.head()

在这里插入图片描述

我们再次查看数据类型:

df.dtypes

在这里插入图片描述

不过我们的计数还不是一个对象,我需要再次进行转换:

df['Year'] = df['Year'].astype(str)
df.dtypes

在这里插入图片描述

现在都转换成object类型了,然后我们还将我们之前创建两个标识Period和Day删掉,我们有前面的时间信息了,它们就是重复的。

九、删除分析字段

df.drop(['Period', 'Day', 'Date'], axis=1, inplace=True)
df.dtypes

在这里插入图片描述

在数据分析之前,我们需要查看是否需要账户,因为账户描述里面可能包含相同的信息并且一个可能只是另一个的反映,我们需要确保拥有与账户描述相同数量的账户,如果是这种情况,我们可以删除其中一个,我们将它们附加在一起并检查长度。

首先看看我们有多少账户:

len(df['Account'].unique())

它运行的结果是:

12

然后再看看我们有多少账户描述信息:

len(df['Account Description'].unique())

它运行的结果是:

12

我们把他们组合在一起,我们就有12个组合账户和账号描述。

df['AccountVal'] = df['Account'] + df['Account Description']
df.head()

在这里插入图片描述

再来检查有多少独特的账户:

len(df['AccountVal'].unique())

它允许的结果是:

12

这样可以确定账户描述和账户信息时重复的,我们可以删除账户描述以及账户的Val列

df.drop(['Account Description', 'AccountVal'], axis=1, inplace=True)
df.head()

在这里插入图片描述

然后我们将为分类特征列中的每个值都有一个唯一的列,转换成后面训练能用的格式——热编码

pd.get_dummies(df)

在这里插入图片描述

适用于我们在数据框中获得的每一个分类特征,然后将它们被热编码等效项取代:

df = pd.get_dummies(df)
df.dtypes

在这里插入图片描述

十、最后我想说

前面的基础数据分析以及数据处理已经完成了,接下来就是构建模型以及训练预测评估了,由于篇幅有限,不想让文章过于冗长,所以我将后面的内容放在下一期博客中,这段时间我就会更新下一部分的内容,也是很关键的一部分,谢谢。

本人水平有限,还在学习中,如果以上文章如有错误之处,还请大家为我指出,谢谢!

创作不易,期待得到你们的支持!

在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-北天-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值