Tutorial of Intro to Data Wrangling with Python & R

Author: Haoxiang Qi(齐浩翔)
Date: Feb 8, 2020

前言

我自己也才学R一周多,内容肯定有很多疏漏错误,能力也相对有限,还请大家多多包容。

学习之前建议通过Google或者前辈明确:

  • 作为非CS专业的商学院学生,我为什么要学习编程?
  • 它们创造的价值是否大于我的时间成本?
  • 我是否是个有耐心且能静下心的人?
  • 它们在哪些领域分别有什么优势?

之前一直是使用Python来做数据分析和可视化,Python的可视化库无论是Matplotlib还是Seaborn都让我有些头疼。由于这学期3门课都是以R语言为基础,我于上周开始第一次接触R语言。虽然一开始有些用着不顺手,但是ggplot2确实好用得抵消了我的这些顾虑。考虑到大家因为教授的授课节奏而困扰,这里我也就顺便梳理了一下Python和R的数据处理的基本操作。

常用包

常用入门R包:reticulate, fpp2(自带ggplot2), Rmisc, dplyr, tidyr
使用install.packages()安装

常用入门Python包: pandas(自带numpy), re, dfply(自带pipe), seaborn(自带matplotlib)
打开Anaconda-Navigator>Environments>下拉菜单选中ALL>搜索并一次勾选包>点击Apply安装 (若失败还可以使用pip安装)
screenshot1

环境配置

之所以选择RStuido作为IDE,是因为这是目前为止最适合Python和R同时操作的IDE了。虽然Jupyter Notebook 远比RStuido的Markdown方便编辑,但是RStuido简洁方便的包管理,高度契合ggplot绘图的界面,Python和R无缝的变量传递,都让我最后选择了它。如果只想单独学习R或者Python的同学,可以跳过这些操作。

Python和R环境安装教程:
1. 先安装Anaconda, 再单独下载并按顺序安装R和R studio
2. 打开R studtio 并新建R Markdown文件(并按提示安装所需包)
3. 建议安装下面提到的所有包
4. 新建markdown文件 screenshot1
5. 删除所有内容,并新建一个R的chunk,在其中输入以下内容并运行(以后每次重启RStudio后都需要运行一次)
screenshot1
6. 无报错后在use_condaenv(“Anaconda”)前加上引号注释掉
7. 随后即可开始在不同的chunk中同时使用R和Python了

Hints:
Python中调用R变量为r.*
R中调用Python变量为py$*

基础语法

数据处理

这里演示用的主要是R语言的diamonds数据集

管道

Python中的dfply包,和R中的dplyr包都带有这一功能。
pipe管道是一种简化数据处理流程的手段,它通过符号将数据传递入下一个function中进行处理,以实现简化代码节约内存的目的。
Python和R的管道使用略有不同,Python使用>>,R使用%>%。后面也会经常使用,有兴趣可以去了解%T>%, %<>%, %$%等

筛选

Python

##    carat   cut color clarity  depth  table  price     x     y     z
## 2   0.23  Good     E     VS1   56.9   65.0    327  4.05  4.07  2.31
## 4   0.31  Good     J     SI2   63.3   58.0    335  4.34  4.35  2.75

R

## # A tibble: 3 x 10
##   carat cut   color clarity depth table price     x     y     z
##   <dbl> <ord> <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
## 1  0.23 Good  E     VS1      56.9    65   327  4.05  4.07  2.31
## 2  0.31 Good  J     SI2      63.3    58   335  4.34  4.35  2.75
## 3  0.3  Good  J     SI1      64      55   339  4.25  4.28  2.73

选择列

Python

##        cut color
## 0    Ideal     E
## 1  Premium     E
## 2     Good     E

R

## # A tibble: 3 x 2
##   cut     color
##   <ord>   <ord>
## 1 Ideal   E    
## 2 Premium E    
## 3 Good    E

取样

Python

##        carat      cut color clarity  depth  table  price     x     y     z
## 40767    0.4    Ideal     E    VVS2   62.4   59.0   1166  4.70  4.73  2.94
## 31983    0.3    Ideal     F     VS2   62.7   57.0    776  4.31  4.27  2.69
## 29847    0.3  Premium     D     VS2   61.9   58.0    710  4.28  4.32  2.66

R

## # A tibble: 3 x 3
##   clarity cut         x
##   <ord>   <ord>   <dbl>
## 1 SI2     Ideal    3.95
## 2 SI1     Premium  3.89
## 3 VS1     Good     4.05

删除列

Python

##    carat      cut clarity  depth  price     x     y     z
## 0   0.23    Ideal     SI2   61.5    326  3.95  3.98  2.43
## 1   0.21  Premium     SI1   59.8    326  3.89  3.84  2.31
## 2   0.23     Good     VS1   56.9    327  4.05  4.07  2.31

R

## # A tibble: 3 x 8
##   carat cut     clarity depth price     x     y     z
##   <dbl> <ord>   <ord>   <dbl> <int> <dbl> <dbl> <dbl>
## 1  0.23 Ideal   SI2      61.5   326  3.95  3.98  2.43
## 2  0.21 Premium SI1      59.8   326  3.89  3.84  2.31
## 3  0.23 Good    VS1      56.9   327  4.05  4.07  2.31

新建计算列

Python

##    carat      cut color clarity  depth  ...     x     y     z  x_plus_y        xyz
## 0   0.23    Ideal     E     SI2   61.5  ...  3.95  3.98  2.43      7.93  38.202030
## 1   0.21  Premium     E     SI1   59.8  ...  3.89  3.84  2.31      7.73  34.505856
## 2   0.23     Good     E     VS1   56.9  ...  4.05  4.07  2.31      8.12  38.076885
## 
## [3 rows x 12 columns]

R

## # A tibble: 3 x 2
##   x_plus_y   xyz
##      <dbl> <dbl>
## 1     7.93  38.2
## 2     7.73  34.5
## 3     8.12  38.1

映射分级

Python

##    carat      cut color clarity  depth  ...  price     x     y     z  price_level
## 0   0.23    Ideal     E     SI2   61.5  ...    326  3.95  3.98  2.43            D
## 1   0.21  Premium     E     SI1   59.8  ...    326  3.89  3.84  2.31            D
## 2   0.23     Good     E     VS1   56.9  ...    327  4.05  4.07  2.31            D
## 
## [3 rows x 11 columns]

R

## # A tibble: 3 x 11
##   carat cut     color clarity depth table price     x     y     z price_class
##   <dbl> <ord>   <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl> <chr>      
## 1  0.23 Ideal   E     SI2      61.5    55   326  3.95  3.98  2.43 D          
## 2  0.21 Premium E     SI1      59.8    61   326  3.89  3.84  2.31 D          
## 3  0.23 Good    E     VS1      56.9    65   327  4.05  4.07  2.31 D

上下粘合列/行

Python

##        carat        cut color clarity  depth  table  price     x     y     z
## 0       0.23      Ideal     E     SI2   61.5   55.0    326  3.95  3.98  2.43
## 1       0.21    Premium     E     SI1   59.8   61.0    326  3.89  3.84  2.31
## 53937   0.70  Very Good     D     SI1   62.8   60.0   2757  5.66  5.68  3.56
## 53938   0.86    Premium     H     SI2   61.0   58.0   2757  6.15  6.12  3.74
## 53939   0.75      Ideal     D     SI2   62.2   55.0   2757  5.83  5.87  3.64
## 3642    0.90  Very Good     G     SI2   64.2   60.0   3437  6.02  6.09  3.89
## 34992   0.35      Ideal     E    VVS2   61.3   56.0    881  4.54  4.60  2.80
## 20848   1.50       Good     E     SI2   63.9   58.0   9072  7.26  7.21  4.62

R

## # A tibble: 3 x 6
##   carat cut     color     x     y     z
##   <dbl> <ord>   <ord> <dbl> <dbl> <dbl>
## 1  0.23 Ideal   E      3.95  3.98  2.43
## 2  0.21 Premium E      3.89  3.84  2.31
## 3  0.23 Good    E      4.05  4.07  2.31

排序

Python

##        carat        cut color clarity  depth  table  price     x     y     z
## 27749   2.29    Premium     I     VS2   60.8   60.0  18823  8.50  8.47  5.16
## 27748   2.00  Very Good     G     SI1   63.5   56.0  18818  7.90  7.97  5.04
## 27747   1.51      Ideal     G      IF   61.7   55.0  18806  7.37  7.41  4.56

R

## # A tibble: 3 x 10
##   carat cut     color clarity depth table price     x     y     z
##   <dbl> <ord>   <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
## 1  0.23 Ideal   E     SI2      61.5    55   326  3.95  3.98  2.43
## 2  0.21 Premium E     SI1      59.8    61   326  3.89  3.84  2.31
## 3  0.23 Good    E     VS1      56.9    65   327  4.05  4.07  2.31
## # A tibble: 3 x 10
##   carat cut       color clarity depth table price     x     y     z
##   <dbl> <ord>     <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
## 1  2.29 Premium   I     VS2      60.8    60 18823  8.5   8.47  5.16
## 2  2    Very Good G     SI1      63.5    56 18818  7.9   7.97  5.04
## 3  1.51 Ideal     G     IF       61.7    55 18806  7.37  7.41  4.56

改列名

Python

##    carat      CUT color clarity  depth  table  price     x     y     z
## 0   0.23    Ideal     E     SI2   61.5   55.0    326  3.95  3.98  2.43
## 1   0.21  Premium     E     SI1   59.8   61.0    326  3.89  3.84  2.31

R

## # A tibble: 2 x 10
##   carat CUT     color clarity depth table price     x     y     z
##   <dbl> <ord>   <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
## 1  0.23 Ideal   E     SI2      61.5    55   326  3.95  3.98  2.43
## 2  0.21 Premium E     SI1      59.8    61   326  3.89  3.84  2.31

排序

Python

##    carat      cut color clarity  depth  ...  price     x     y     z  price_rank
## 0   0.23    Ideal     E     SI2   61.5  ...    326  3.95  3.98  2.43           1
## 1   0.21  Premium     E     SI1   59.8  ...    326  3.89  3.84  2.31           1
## 2   0.23     Good     E     VS1   56.9  ...    327  4.05  4.07  2.31           2
## 
## [3 rows x 11 columns]

R

## # A tibble: 3 x 11
##   carat cut     color clarity depth table price     x     y     z price_rank
##   <dbl> <ord>   <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>      <int>
## 1  0.23 Ideal   E     SI2      61.5    55   326  3.95  3.98  2.43          1
## 2  0.21 Premium E     SI1      59.8    61   326  3.89  3.84  2.31          2
## 3  0.23 Good    E     VS1      56.9    65   327  4.05  4.07  2.31          3

窗口移动

Python

##    carat      cut color clarity  depth  ...  price     x     y     z  lag_price
## 0   0.23    Ideal     E     SI2   61.5  ...    326  3.95  3.98  2.43        NaN
## 1   0.21  Premium     E     SI1   59.8  ...    326  3.89  3.84  2.31        NaN
## 2   0.23     Good     E     VS1   56.9  ...    327  4.05  4.07  2.31        NaN
## 3   0.29  Premium     I     VS2   62.4  ...    334  4.20  4.23  2.63        NaN
## 4   0.31     Good     J     SI2   63.3  ...    335  4.34  4.35  2.75      326.0
## 
## [5 rows x 11 columns]

R

## # A tibble: 3 x 11
##   carat cut     color clarity depth table price     x     y     z price_lead
##   <dbl> <ord>   <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>      <int>
## 1  0.23 Ideal   E     SI2      61.5    55   326  3.95  3.98  2.43         NA
## 2  0.21 Premium E     SI1      59.8    61   326  3.89  3.84  2.31         NA
## 3  0.23 Good    E     VS1      56.9    65   327  4.05  4.07  2.31        326
## # A tibble: 3 x 11
##   carat cut     color clarity depth table price     x     y     z cumsum_carat
##   <dbl> <ord>   <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>        <dbl>
## 1  0.23 Ideal   E     SI2      61.5    55   326  3.95  3.98  2.43         0.23
## 2  0.21 Premium E     SI1      59.8    61   326  3.89  3.84  2.31         0.44
## 3  0.23 Good    E     VS1      56.9    65   327  4.05  4.07  2.31         0.67

长转宽数据

Python

##     Player Introduction   Message
## 0  Player1         name     Sulie
## 1  Player1    education    master
## 2  Player1          sex      male
## 3  Player2         name     LuBan
## 4  Player2    education  Bachelor
## 5  Player2          sex      male
## 6  Player3         name    ZhenJi
## 7  Player3    education       PhD
## 8  Player3          sex    female
##     Player education    name     sex
## 0  Player1    master   Sulie    male
## 1  Player2  Bachelor   LuBan    male
## 2  Player3       PhD  ZhenJi  female

R

## # A tibble: 3 x 4
##   Player  name   education sex   
##   <chr>   <chr>  <chr>     <chr> 
## 1 Player1 Sulie  master    male  
## 2 Player2 LuBan  Bachelor  male  
## 3 Player3 ZhenJi PhD       female

宽转长数据

Python

##     Player Introduction Message
## 0  Player1         name   Sulie
## 1  Player2         name   LuBan
## 2  Player3         name  ZhenJi

R

## # A tibble: 9 x 3
##   Player  Introduction Message 
##   <chr>   <chr>        <chr>   
## 1 Player1 name         Sulie   
## 2 Player1 education    master  
## 3 Player1 sex          male    
## 4 Player2 name         LuBan   
## 5 Player2 education    Bachelor
## 6 Player2 sex          male    
## 7 Player3 name         ZhenJi  
## 8 Player3 education    PhD     
## 9 Player3 sex          female

填充空值

Python

##              cut   price
## 53840       Good  2738.0
## 53841  Very Good  2739.0
## 53842      Ideal  2739.0
## 53843      Ideal  2739.0
## 53844  Very Good  2740.0
## ...          ...     ...
## 53935      Ideal     NaN
## 53936       Good     NaN
## 53937  Very Good     NaN
## 53938    Premium     NaN
## 53939      Ideal     NaN
## 
## [100 rows x 2 columns]
##              cut        price
## 53840       Good  2738.000000
## 53841  Very Good  2739.000000
## 53842      Ideal  2739.000000
## 53843      Ideal  2739.000000
## 53844  Very Good  2740.000000
## ...          ...          ...
## 53935      Ideal  2747.838710
## 53936       Good  2750.333333
## 53937  Very Good  2747.920000
## 53938    Premium  2748.125000
## 53939      Ideal  2747.838710
## 
## [100 rows x 2 columns]

字符串处理

Python(这里略过R, 因为字符串处理是Python的强项)

常用自带字符串函数

## '  Item quantity '
## 'Item quantity'
## 'Item_quantity'
##    Carat    Cut Color Clarity  Depth  Table  Price     X     Y     Z
## 0   0.23  Ideal     E     SI2   61.5   55.0    326  3.95  3.98  2.43

正则表达式re模块
re是数据清洗的核心模块之一,也是许多爬虫脚本得以正常运行的基本。
不过正则表达式较为复杂,这里不多赘述。
有兴趣可以点击链接学习,学明白之后用处很多,并且R和SQL的正则表达式也都相似。
https://www.liaoxuefeng.com/wiki/1016959663602400/1017639890281664

## ['qihaoxiang1', 'Python3']
## 0      Ideal123
## 1    Premium123
## 2       Good123
## 3    Premium123
## 4       Good123
## Name: Cut, dtype: category
## Categories (5, object): [Fair123 < Good123 < Very Good123 < Premium123 < Ideal123]
## 0      Ideal
## 1    Premium
## 2       Good
## 3    Premium
## 4       Good
## Name: Cut, dtype: category
## Categories (5, object): [Fair < Good < Very Good < Premium < Ideal]

总结:

我的学习顺序:了解大致功能 >> 购买书籍或者网课学习基础语法 >> 实操 >> 结合官方文档学习各类第三方包 >> 总结梳理形成知识体系 >> 尝试应用新知识输出分析报告 >> 阅读Github,文章里浏览优秀分析报告和代码

这是一个大致的顺序,细节还是因人而异的。在上面的包熟练之后,可以着手尝试更丰富的第三方包,可以进行机器学习,深度学习,爬虫,绘制各类图表,连接数据库等一系列进阶操作。

pandas官方文档:https://pandas.pydata.org/pandas-docs/stable/reference/index.html
ggplot2官方文档:https://ggplot2.tidyverse.org/reference/index.html
dplyr官方文档:https://dplyr.tidyverse.org/reference/index.html

附录: nCov疫情可视化数据分析(左手R右手Python实战)

Author: Haoxiang Qi(齐浩翔)
Date: Feb 8, 2020
Data from: GuangchuangYu (Github), jianxu305 (Github)

R包获取数据

##   name confirm suspect dead heal
## 1 湖北   27100       0  780 1439
## 2 广东    1120       0    1  125
## 3 浙江    1075       0    0  173
##   confirm suspect dead heal deadRate healRate  date
## 1      41       0    1    0      2.4      0.0 01.13
## 2      41       0    1    0      2.4      0.0 01.14
## 3      41       0    2    5      4.9     12.2 01.15

全国累计总人数趋势图

数据处理

##    number   date condition
## 0       0  01.13        治愈
## 1       0  01.14        治愈
## 2       5  01.15        治愈

可视化

分析:
1. 可以非常明显的看出确诊人数和疑似人数仍然持上升趋势,其中确诊人数呈现近似指数增长,预计2月9日即突破4万确诊,形势依然不容乐观。
2. 全国治愈人数逐渐上升突破1542人,各地的物资医疗支援开始初见成效。

有兴趣的同学可以查看下面的使用R语言预测拐点的链接
https://openr.pzhao.org/zh/blog/ncovr-03/

全国确诊/疑似百分比堆积图

数据处理

##     number   date condition  total     ratio
## 51   27657  02.07        疑似  62255  0.444253
## 52   28942  02.08        疑似  66193  0.437237
## 53   37251  02.08        确诊  66193  0.562763

可视化

分析:
1. 确诊人数占比近日出现上升,并于2月4日超过50%,说明确诊能力得到提升,感染人群容易被控制。
2. 确诊能力的提升使得更多处于潜伏期的人群能够被隔离,减少与未染病人群的接触,降低疫情扩大的可能。

R包的数据比较少,下面使用Python获取更多数据

## 最近更新于:  2020-02-09 10:23:01.835000
## 数据日期范围:  2020-01-24 to 2020-02-09
## 数据条目数:  26724
##       provinceName cityName  confirmed  cured  dead  updateDate
## 25734          云南省      丽江市          1      0     0  2020-01-24
## 25732          云南省       昆明          3      0     0  2020-01-24
## 25733          云南省    西双版纳州          1      0     0  2020-01-24

人口-GDP-死亡数气泡关系图 (除武汉外死亡数前十城市)

数据处理

##   provinceName cityName  confirmed  cured  dead  updateDate   GDP  population
## 0          湖北省       黄冈       2141    137    43  2020-02-09  2035         750
## 1          湖北省       孝感       2436     45    29  2020-02-09  1912         530
## 2          湖北省       鄂州        639     42    21  2020-02-09  1005         108

可视化

分析:
手动录入10座城市的GDP和人口数据,并加入全国人均GDP标准线,想探究目前富裕程度和死亡人数的关系。
1. 襄阳和宜昌作为湖北省老二老三,拥有较为优良的医疗条件,所以即便人口众多也能尽可能降低死亡数。
2. 就死亡数来看,可能黄冈和孝感对医疗力量的需求更大,应加大对这两座城市的救援力度。

四省治愈率趋势图(湖北/浙江/河南/广东)

数据处理

##     provinceName  updateDate  confirmed  cured  dead
## 347          湖北省  2020-02-09      27100   1439   780
## 346          湖北省  2020-02-08      24953   1218   699
## 345          湖北省  2020-02-07      22112    867   618

可视化

# R
# 新建治愈率计算列并选出三列
total <- py$total %>% mutate(cured_ratio = cured / confirmed * 100) %>% select(
  "provinceName", "updateDate", "cured_ratio")

# 定义新函数:方便一次性画出四张图
plot_provinces <- function(info, flag_title, flag_title_x, flag_title_y)
  {
  # 传递参数进入theme以方便消除多余的标题
  if (flag_title == TRUE)  
    title = element_blank()
  else
    title = element_text(size = 10, face = "bold")
  if (flag_title_x == TRUE)
    title_x = element_blank()
  else
    title_x = element_text(size = 8)
  if (flag_title_y == TRUE)
    title_y = element_blank()
  else
    title_y = element_text(size = 8)
  if (info == "浙江省")
    {mannul_colors = c("#E69F00", "#56B4E9")
    mannul_shapes = c(16, 17)}
  else
    {mannul_colors = c("#56B4E9", "#E69F00")
    mannul_shapes = c(17, 16)}
  
ggplot(total %>% filter(provinceName == info | provinceName == "全国平均"), aes(
  x=as.Date(updateDate, "%Y-%m-%d"), y=cured_ratio, color=provinceName)) + 
  geom_line(size=.7, alpha=.5) +
  geom_point(aes(shape=provinceName)) +
  theme_classic() +
  scale_x_date(date_labels = "%m/%d", breaks = "3 days") +
  xlab("日期") +
  ylab("治愈率 (%)") +
  geom_hline(yintercept = 5, color='black', size=.5, alpha=.7, linetype="dotted") +
  geom_hline(yintercept = 10, color='black', size=.5, alpha=.7, linetype="dotted") +
  geom_hline(yintercept = 15, color='black', size=.5, alpha=.7, linetype="dotted") +
  ylim(0,15) +
  ggtitle("四省治愈率趋势图(湖北/浙江/河南/广东)") +
  scale_color_manual(values=mannul_colors) +
  scale_shape_manual(values=mannul_shapes) +
  theme(text = element_text(family = "Source Han Sans CN")) +
  theme(
    plot.title = title,
    axis.text=element_text(size=8,face="bold"),
    axis.title.x=title_x,
    axis.title.y=title_y,
    legend.text = element_text(size=8),
    legend.title = element_text(size=8),
    )
}

# 调用函数绘制图
hubei <- plot_provinces("湖北省", FALSE, TRUE, FALSE)
henan <- plot_provinces("河南省", TRUE, FALSE, FALSE)
zhejiang <- plot_provinces("浙江省", TRUE, TRUE, TRUE)
guangdong <- plot_provinces("广东省", TRUE, FALSE, TRUE)

# 拼接为一张图
multiplot(hubei, henan, zhejiang, guangdong, cols=2)

分析:
1. 作为确诊人数最多的四省,除湖北外,其他省均达到或超过10%的治愈率,相信随着时间的增长,会有更多患者得以康复。
2. 正是由于浙江和河南政府的积极举措,使得这两省的治愈率最为理想,值得其他省份借鉴。

全国新增确诊趋势图

数据处理

##       ticker  updateDate  new_confirmed
## 35  全国(不含湖北)  2020-01-28          525.0
## 13       湖北省  2020-02-07         2447.0
## 38  全国(不含湖北)  2020-01-31         1070.0

可视化

分析:
1. 可以非常直观地看出,除武汉外,其余省份疫情得到有效的控制,新增确诊人数呈现稳定下降趋势。
2. 武汉以及湖北省疫情最为严峻,目前还未看出好转迹象。