美文网首页
[Python/R语言] 用R和python解决数据分析120题

[Python/R语言] 用R和python解决数据分析120题

作者: 半为花间酒 | 来源:发表于2020-04-15 13:43 被阅读0次

    转载请注明:陈熹 chenx6542@foxmail.com (简书号:半为花间酒)
    若公众号内转载请联系公众号:早起Python
    题源:
    公众号 早起python 《Pandas进阶修炼120题》

    数据:
    https://pan.baidu.com/s/1YTYB4zuyPNYDoNoj2pCh6Q
    提取码:p5yn

    数据分析120题系列:

    为什么出这个专题:

    R语言和pandas都是数据处理的重要工具
    而二者的高下争论时有存在
    我相信对于数据而言没有绝对的孰优孰劣
    需要做的应该是在必要时权衡最合适的办法

    感谢 公众号早起python 提供数据分析120题
    这些题目是一个契机
    帮助我比较了两种语言处理不同问题的共性
    当然也发现了各自的灵活和缺陷

    它们覆盖多数数据分析初期可能遇到的问题
    无论是对R语言还是对python技能的提升
    相信都有很大帮助

    (陈熹 2020年4月)

    • python解法
    import pandas as pd
    import numpy as np
    
    df = pd.read_excel(r'C:\Users\chenx\Documents\Data Analysis\pandas120.xlsx')
    
    • R解法
      R语言原生函数处理excel不友好,直接读取日期时间数据会变成实数
      openxlsx::read.xlsx中的detectDates参数只能识别纯日期
      as.Data转换该列后时间数据丢失,只有日期
      可以先把excel文件转存为csv后用readr包读取
      另外再推荐非常智能的rio包,对格式的识别和属性的解析非常强
    # 该方法不理想
    library(openxlsx)
    df <- read.xlsx('pandas120.xlsx',detectDates = T)
    df$createTime <- as.Date(df$createTime,origin="1900-01-01")
    
    # 转存csv后再读
    library(readr)
    df <- read_csv('pandas120.csv')
    # 本题用这种方法,但需要注意createTime属性被解析成chr
    
    # 强烈推荐rio包,一步到位,功能强大,解析成功率高
    df <- rio::import('pandas120.xlsx')
    
    pandas / R
    • python解法
    df.head()
    
    • R解法
    # 默认是6行,可指定行数
    head(df,5)
    
    pandas / R
    • python解法
    # 方法一:apply + 自定义函数
    def func(df):
        lst = df['salary'].split('-')
        smin = int(lst[0].strip('k'))
        smax = int(lst[1].strip('k'))
        df['salary'] = int((smin + smax) / 2 * 1000)
        return df
    
    df = df.apply(func,axis=1) 
    
    # 方法二:iterrows + 正则
    import re
    
    for index,row in df.iterrows():
        nums = re.findall('\d+',row[2])
        df.iloc[index,2] = int(eval(f'({nums[0]} + {nums[1]}) / 2 * 1000'))
    
    • R解法
      同理也可以自定义函数 + apply,这里用其他方法
    library(stringr)
    df$salary <- df$salary %>% 
      str_replace_all('k','') %>% 
      str_split('-',simplify = T) %>% 
      apply(2,as.numeric) %>% 
      rowMeans() * 1000
    
    pandas / R
    • python解法
    df.groupby('education').mean()
    
    • R解法
    df %>% 
      group_by(education) %>% 
      summarise(mean = mean(salary))
    
    pandas / R
    • python解法
    for index,row in df.iterrows():
       df.iloc[index,0] = df.iloc[index,0].to_pydatetime().strftime("%m-%d")
    
    • R解法
      转化后该列属性是 字符串,R中对时间格式要求严格
    df$createTime <- as.Date(df$createTime) %>% 
      str_replace('2020-','')
    
    pandas / R
    • python解法
    df.info()
    
    • R解法
    str(df)
    
    # 内存查看需要用到其他的库
    library(pryr)
    object_size(df)
    # 6.66 kB
    
    pandas / R
    • python解法
    df.describe()
    
    • R解法
    summary(df)
    
    pandas / R
    • python解法
    bins = [0,5000, 20000, 50000]
    group_names = ['低', '中', '高']
    df['categories'] = pd.cut(df['salary'], bins, labels=group_names)
    
    • R解法
      用ifelse也可以
      底层原理有差别但实现结果一样
    df <- df %>% 
      mutate(categories = case_when(
        salary >= 0 & salary < 5000 ~ '低',
        salary >= 5000 & salary < 20000 ~ '低',
        TRUE ~ '高'
      ))
    
    pandas / R
    • python解法
    df.sort_values('salary', ascending=False)
    
    • R解法
    df %>% 
      arrange(desc(salary))
    
    pandas / R
    • python解法
    df.iloc[32]
    
    • R解法
    df[33,]
    
    pandas / R
    • python解法
    np.median(df['salary'])
    # 17500.0
    
    • R解法
    median(df$salary)
    # [1] 17500
    


    (R的可视化采用ggplot2包
    • python解法
    # Jupyter运行matplotlib成像需要运行魔术命令
    %matplotlib inline
    
    plt.rcParams['font.sans-serif'] = ['SimHei'] # 解决中文乱码
    plt.rcParams['axes.unicode_minus'] = False # 解决符号问题
    
    import matplotlib.pyplot as plt
    plt.hist(df.salary)
    
    # 也可以用原生绘图
    df.salary.plot(kind='hist')
    
    • R解法
    library(ggplot2)
    library(patchwork)
    
    df %>% 
      ggplot(aes(salary)) +
      geom_histogram() + 
      df %>% 
      ggplot(aes(salary)) +
      geom_histogram(bins = 10) # 这个跟python的bins一致
    
    pandas / R
    • python解法
    df.salary.plot(kind='kde',xlim = (0,70000))
    
    • R解法
    df %>% 
      ggplot(aes(salary)) +
      geom_density() +
      xlim(c(0,70000))
    
    pandas / R
    • python解法
    del df['categories']
    # 等价于
    df.drop(columns=['categories'], inplace=True)
    
    • R解法
    df <- df[,-4]
    # 提高可读性可采用如下代码
    df <- df %>% 
      select(-c('categories'))
    
    pandas / R
    • python解法
    df['test'] = df['education'] + df['createTime']
    
    • R解法
    df <- df %>% 
      mutate(test = paste0(df$education,df$createTime))
    
    pandas / R
    • python解法
    df["test1"] = df["salary"].map(str) + df['education']
    
    • R解法
    df <- df %>% 
      mutate(test1 = 
               paste0(df$salary,df$education))
    
    pandas / R
    • python解法
    df[['salary']].apply(lambda x: x.max() - x.min())
    # salary    41500
    # dtype: int64
    
    • R解法
    df %>% 
      summarise(delta = max(salary) - min(salary)) %>% 
      unlist()
    # delta 
    # 41500 
    

    • python解法
    pd.concat([df[1:2], df[-1:]])
    
    • R解法
    rbind(df[1,],df[dim(df)[1],])
    
    pandas / R
    • python解法
    df.append(df.iloc[7])
    
    • R解法
    rbind(df,df[8,])
    
    pandas / R
    • python解法
    df.dtypes
    # createTime    object
    # education     object
    # salary         int64
    # test          object
    # test1         object
    # dtype: object
    
    • R解法
    str(df)
    # tibble [135 x 5] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
    #  $ createTime: chr [1:135] "03-16" "03-16" "03-16" "03-16" ...
    #  $ education : chr [1:135] "本科" "本科" "不限" "本科" ...
    #  $ salary    : num [1:135] 27500 30000 27500 16500 15000 14000 23000 12500 7000 16000 ...
    #  $ test      : chr [1:135] "本科03-16" "本科03-16" "不限03-16" "本科03-16" ...
    #  $ test1     : chr [1:135] "27500本科" "30000本科" "27500不限" "16500本科" ...
    

    • python解法
    df.set_index("createTime")
    
    • R解法
      createTime中含大量重复数据
      R中行索引要求必须是无重复,因此无法设置
      方法如下:
    df %>% 
      tibble::column_to_rownames('createTime')
    
    pandas / R
    • python解法
    df1 = pd.DataFrame(pd.Series(np.random.randint(1, 10, 135)))
    
    • R解法
    df1 <- sapply(135,function(n) {
      replicate(n,sample(1:10,1))
    })
    # 列名暂时不一样,下一题重命名
    
    pandas / R
    • python解法
    df= pd.concat([df,df1],axis=1)
    
    • R解法
    df <- cbind(df,df1) %>% 
      rename(`0` = df1)
    # 非常规命名需要用``包裹变量名
    
    pandas / R
    • python解法
    df["new"] = df["salary"] - df[0]
    
    • R解法
    df <- df %>% 
      mutate(new = salary - `0`)
    
    pandas / R
    • python解法
    df.isnull().values.any()
    # False
    
    • R解法
    # 这个包的结果呈现非常有趣
    library(mice)
    md.pattern(df)
    
    R
    • python解法
    df['salary'].astype(np.float64)
    
    • R解法
    as.double(df2$salary)
    
    pandas / R
    • python解法
    len(df[df['salary'] > 10000])
    # 119
    
    • R解法
    df %>% 
      filter(salary > 10000) %>% 
      dim(.) %>% 
      .[1]
    # [1] 119
    

    • python解法
    df.education.value_counts()
    
    • R解法
    table(df$education)
    

    • python解法
    df['education'].nunique()
    # 4
    
    • R解法
    length(unique(df$education))
    # [1] 4
    

    • python解法
    rowsums = df[['salary','new']].apply(np.sum, axis=1)
    res = df.iloc[np.where(rowsums > 60000)[0][-3:], :]
    
    • R解法
    df[df$salary + df$new > 60000,] %>% 
      .[nrow(.)-3+1:nrow(.),] %>% 
      na.omit(.)
    

    相关文章

      网友评论

          本文标题:[Python/R语言] 用R和python解决数据分析120题

          本文链接:https://www.haomeiwen.com/subject/iknfvhtx.html