参考书目:《深入浅出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接口进行爬取。