参考书目:《深入浅出Pandas:利用Python进行数据处理与分析》
pandas里面各个模块基本都展示得差不多了,后面就是使用pandas进行数据分析的案例。由于pandas的处理都是向量化操作,会比自己用列表字典写循环来得快。在熟悉了前面的基础操作后,我们后面的案例都是采用高级一点的链式法则的编程思想,即一行代码就可以进行一个项目分析,这样可以保证代码的简介性。链式法则的mode如下:
(
pd.concat(pd.read_csv('data1.csv'), pd.read_csv('data2.csv'))
.fillna(...)
.append(...)
.set_index('...')
.query('some_condition')
.assign(new_column = pd.cut(...))
.eval('...')
.pivot_table(...)
.pipe(fun) # 应用管道方法
.rename(...) # 修改轴名
.loc[lambda x: ...] # 筛选
.mask(df.A>=2,1) # 修改数据
.plot # 绘图
.line(...)
)
这样相当于一行代码解决了问题,而且没有改变原来的数据,简介方便。
下面来介绍一些数据分析小案例
有一组时间序列的销售数据,要比较一下同期的销售额变化,即比较去年11月10日的销售额和今年的11月10日销售额变化,具体代码如下:
首先构造数据:
df=pd.DataFrame({'日期':pd.date_range('2020-11-5','2020-11-10'),'销售额':np.random.randint(10,100,size=(6,))})
df2=pd.DataFrame({'日期':pd.date_range('2019-11-6','2019-11-10'),'销售额':np.random.randint(10,100,size=(5,))})
df=df.append(df2)
df.set_index('日期',inplace=True)
df=df.sort_index(ascending=False)
df
使用链式法则,比较同月同日的差值,然后画图
( df
.groupby([lambda x:x.month,lambda x:x.day])
.apply(lambda x: x.diff(-1))
.loc[lambda x:x.index.year==2020]
.plot()
)
计算最近100年的圣诞节分别都是星期几,星期分布。
#代码实现如下:
(
# 生成100年时间序列
pd.Series(pd.date_range('1920', '2021'))
# 筛选 12月25日 的所有日期
.loc[lambda s: (s.dt.month==12) & (s.dt.day==25)]
.dt.dayofweek # 转为星期数
.add(1) # 由于0代表周一,对序列加1,符合日常认知
.value_counts() # 重复值计数
.sort_values() # 排序,星期从1-7
.plot
.bar() # 绘制柱状图
)
分布还是很均匀的,星期一到七都有,数量都差不多。上面代码是一行就能搞定。
这是一个二项分布,可以用排列组合概率论来计算。某一天下雨的概率为0.4,那么三天里有两天下雨的概率是3(C32)*0.4*0.4*0.6=0.28886。使用代码模拟计算这个概率:
rng = np.random.default_rng()
days = 100000
arr = rng.integers(0, 1000, days)
(
pd.DataFrame()
.assign(x=arr)
.astype(str)
.assign(x=lambda d: d.x.str.zfill(3))
.assign(a=lambda d: d.x.str.count(r'1|2|3|4'))
.query('a==2')
)
a为下雨次数,筛选出a为2的个数,再除以总体个数就是概率
len(_)/days
和理论值差不多。
这个是腾讯的新冠疫情每日数更新的小程序。找这个网站的api,然后获取数据解析提取每个国家的死亡人数。
import requests # 安装 pip install requests
s = requests.Session()
# 访问数据
covid19 = s.get('https://api.inews.qq.com/newsqa/v1/automation/foreign/country/ranklist')
# 数据文本
j_data = covid19.text
# 读取解析JSON
pd.read_json(j_data).data
data = [(i['name'],i['dead']) for i in pd.read_json(j_data).data]
df = pd.DataFrame(data, columns=['国家', '死亡人数'])
df
这算是一个比较简单的爬虫案例了。当然这个api只是2021年各国的死亡人数,想要动态观看每天的感染人数和死亡人数,需要找更好的api接口进行爬取。