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

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

作者: 半为花间酒 | 来源:发表于2020-04-17 12:08 被阅读0次

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

    数据:
    https://pan.baidu.com/s/1DBWTFKrAeX3s9Nhmb7YvnA
    提取码:wr6e

    数据分析120题系列:

    为什么出这个专题:

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

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

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

    (陈熹 2020年4月)

    • python解法
    import pandas as pd
    import numpy as np
    print(np.__version__)
    # 1.16.5
    print(pd.__version__)
    # 0.25.1
    
    • R解法
      R中没有pandas和numpy
      以其他包为例,查询包版本的命令如下
    packageVersion("tidyverse")
    # [1] ‘1.3.0’
    packageVersion("dplyr")
    # [1] ‘0.8.99.9002’
    

    • python解法
    tem = np.random.randint(1,100,20)
    df1 = pd.DataFrame(tem)
    
    • R解法
    df1 <- sapply(20,function(n) {
      replicate(n,sample(1:100,1))
    }) %>% 
      as.data.frame(.) %>% 
      dplyr::rename(`0` = V1)
    
    pandas / R
    • python解法
    tem = np.arange(0,100,5)
    df2 = pd.DataFrame(tem)
    
    • R解法
    df2 <- as.data.frame(seq(0,99,5)) %>% 
      dplyr::rename(`0` = "seq(0, 99, 5)")
    
    pandas / R
    • python解法
    tem = np.random.normal(0, 1, 20)
    df3 = pd.DataFrame(tem)
    
    • R解法
    df3 <- as.data.frame(rnorm(20,0,1)) %>% 
      dplyr::rename(`0` = "rnorm(20, 0, 1)")
    
    pandas / R
    • python解法
    df = pd.concat([df1,df2,df3],axis=0,ignore_index=True)
    
    • R解法
    df <- rbind(df1,df2,df3)
    
    pandas / R
    • python解法
    df = pd.concat([df1,df2,df3],axis=1,ignore_index=True)
    
    • R解法
    df <- cbind(df1,df2,df3)
    names(df) <- c(0,1,2)
    
    pandas / R
    • python解法
    np.percentile(df, q=[0, 25, 50, 75, 100])
    
    • R解法
    summary(unlist(df))
    

    因为df1和df3都是随机的,所以结果不同

    pandas / R
    • python解法
    df.columns = ['col1','col2','col3']
    
    • R解法
    df <- df %>% 
      dplyr::rename(col1 = 1,
                    col2 = 2,
                    col3 = 3)
    # 或者用类似pandas的方法
    names(df) <- c('col1','col2','col3')
    
    pandas / R
    • python解法
    df['col1'][~df['col1'].isin(df['col2'])]
    
    • R解法
    df[!(df$col1 %in% df$col2),1]
    
    pandas / R
    pandas / R
    • python解法
    temp = df['col1'].append(df['col2'])
    temp.value_counts()[:3]
    
    • R解法
    count(unlist(c(df$col1,df$col2))) %>% 
      arrange(desc(freq)) %>% 
      filter(row_number() <= 3) 
    

    因为col1是随机产生的,所以结果不同

    pandas / R
    • python解法
    np.argwhere(df['col1'] % 5==0)
    
    • R解法
    which(df['col1'] %% 5==0)
    
    pandas / R
    • python解法
    df['col1'].diff().tolist()
    
    • R解法
    df %>% 
      summarise(col1 - lag(col1)) %>% 
      na.omit(.) # 不去NA也可以,pandas没有去除
    
    pandas / R
    • python解法
    df.iloc[:, ::-1]
    
    • R解法
    df %>% 
      select(col3,col2,everything())
    
    pandas / R
    • python解法
    df['col1'].take([1,10,15])
    # 等价于
    df.iloc[[1,10,15],0]
    
    • R解法
      python中的数字位置是从0开始的,R是从1开始
      故R中取同个位置需要+1
    df[c(1,10,15) + 1,1]
    
    pandas / R
    • python解法
    res = np.diff(np.sign(np.diff(df['col1'])))
    np.where(res== -2)[0] + 1
    # array([ 2,  4,  7,  9, 12, 15], dtype=int64)
    
    • R解法
    res1 <- which((df$col1 - lag(df$col1) > 0))
    res2 <- which((df$col1 - lead(df$col1) > 0))
    
    intersect(res1,res2)
    # [1]  3  5  7 12 14 17 19
    
    # 另一种方法,类似pandas的用符号判断
    
    res <- sign(df$col1 - lag(df$col1))
    
    which(res - lag(res) == -2) - 1
    # # [1]  3  5  7 12 14 17 19
    

    • python解法
    df[['col1','col2','col3']].mean(axis=1)
    
    • R解法
    rowMeans(df)
    
    pandas / R
    • python解法
    np.convolve(df['col2'], np.ones(3)/3, mode='valid')
    
    • R解法
    library(RcppRoll)
    
    df %>% 
      summarise(avg_3 = roll_mean(col2, n=3))
    
    pandas / R
    • python解法
    df.sort_values("col3",inplace=True)
    
    • R解法
    df <- df %>% 
      arrange(col3)
    
    pandas / R
    • python解法
    df.col1[df['col1'] > 50] = '高'
    
    • R解法
    df[df$col1 > 50,1] <- '高'
    
    pandas / R

    Euclidean distance 欧几里得(欧氏)距离: 两变量差值平方和的平方根

    • python解法
    np.linalg.norm(df['col1']-df['col2'])
    # 194.29873905921264
    
    • R解法
    # 可以利用概念计算
    res <- (df$col1 - df$col2) ^ 2
    sqrt(sum(res))
    # [1] 197.0102
    
    # 也可以利用dist函数,但需要形成两个不同的观测
    dist(rbind(df$col1,df$col2))
    #          1
    # 2 197.0102
    

    • python解法
    df1 = pd.read_csv(r'C:\Users\chenx\Documents\Data Analysis\数据1.csv',encoding='gbk', usecols=['positionName', 'salary'],nrows = 10)
    
    • R解法
      一步读取文件的指定列用readr包或者原生函数都没办法
      如果文件特别大又不想全部再选指定列可以用如下办法
      基本思想先读取较少的数据获取列名
      给目标列以外的列打上NULL导致第二次读取文件时NULL列丢失即可
    res <- read.csv('数据1.csv',encoding = 'GBK',nrows = 3)
    classes <- sapply(res, class)
    classes[-match(c('positionName','salary'),names(classes))] <- 
      rep('NULL', length(classes) - 2)
    
    df <- read.csv('数据1.csv',encoding = 'GBK',nrows = 10,
                   colClasses = classes)
    
    pandas / R
    • python解法
    df2 = pd.read_csv(r'C:\Users\chenx\Documents\Data Analysis\数据2.csv',
                      converters={'薪资水平': lambda x: '高' if float(x) > 10000 else '低'} )
    
    • R解法
      读取文件时用函数改数据确实不会
      留个坑以后有机会填上
      下面采用的策略是先读再修改
    library(readr)
    
    df2 <- read_csv('数据2.csv') %>% 
      mutate('学历要求',
             '薪资水平' = ifelse(
               薪资水平 > 10000,'高','低'))
    
    pandas / R
    • python解法
    df2.iloc[::20, :][['薪资水平']]
    
    • R解法
    df2[seq(1,dim(df2)[1],20),]
    
    pandas / R
    • python解法
      示例即创建含10个0-1随机数的数据框
    df = pd.DataFrame(np.random.random(10)**10, columns=['data'])
    df.round(3)
    
    • R解法
    df <- tibble(data = runif(10)^10)
    round(df,3)
    
    pandas / R
    • python解法
    df.style.format({'data': '{0:.2%}'.format})
    
    • R解法
    tibble(data = str_glue('{round(df$data * 100,2)}%'))
    
    pandas / R
    • python解法
    df['data'].argsort()[len(df)-3]
    
    • R解法
    df %>% 
      mutate(nrow = rownames(.)) %>% 
      arrange(desc(data)) %>% 
      filter(row_number() == 3) %>% 
      select(nrow)
    

    • python解法
    df.iloc[::-1, :]
    
    • R解法
      R顺序确实发生了逆转但行号不变
    df %>% 
      arrange(desc(rownames(.)))
    
    pandas / R
    • python解法
    df1= pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
    'key2': ['K0', 'K1', 'K0', 'K1'],
    'A': ['A0', 'A1', 'A2', 'A3'],
    'B': ['B0', 'B1', 'B2', 'B3']})
    
    df2= pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
    'key2': ['K0', 'K0', 'K0', 'K0'],
    'C': ['C0', 'C1', 'C2', 'C3'],
    'D': ['D0', 'D1', 'D2', 'D3']})
    
    pd.merge(df1, df2, on=['key1', 'key2'])
    
    • R解法
    df1 <- data.frame(
      "key1" = c("K0","K0","K1","K2"),
      "key2" = c("K0","K1","K0","K1"),
      "A" = paste0('A',0:3),
      "B" = paste0('B',0:3)
    )
    
    df2 <- data.frame(
      "key1" = c("K0","K1","K1","K2"),
      "key2" = paste0('K',rep(0,4)),
      "C" = paste0('C',0:3),
      "D" = paste0('D',0:3)
    )
    
    full_join(df1,df2,by = c('key1','key2')) %>% 
      na.omit(.)
    
    pandas / R
    • python解法
    pd.merge(df1, df2, how='left', on=['key1', 'key2'])
    
    • R解法
    left_join(df1,df2,by = c('key1','key2'))
    
    pandas / R
    • python解法
    df = pd.read_csv(r'C:\Users\chenx\Documents\Data Analysis\数据1.csv',encoding='gbk')
    pd.set_option("display.max.columns", None)
    
    • R解法
    df <- read_csv('数据1.csv', locale = locale(encoding = "GBK")) %>% 
      print(width = Inf)
    

    • python解法
    np.where(df.secondType == df.thirdType)
    
    • R解法
    df %>% 
      mutate(nrow = rownames(.)) %>% 
      filter(secondType == thirdType) %>% 
      select(nrow) %>% 
      unlist()
    

    (pandas的行位置从0开始,R则从1开始)

    pandas / R

    返回数据的位置

    • python解法
    np.argwhere(df['salary'] > df['salary'].mean())[2]
    # array([5], dtype=int64)
    
    • R解法
    df %>% 
      mutate(nrow = rownames(.)) %>% 
      filter(salary > mean(salary)) %>% 
      select(nrow) %>% 
      filter(row_number() == 3)
    # # A tibble: 1 x 1
    #    nrow 
    #    <chr>
    #    1 6 
    

    • python解法
    df[['salary']].apply(np.sqrt)
    
    • R解法
    df %>% 
      summarise(salary_sqrt = sqrt(salary))
    
    pandas / R
    • python解法
    df['split'] = df['linestaion'].str.split('_')
    
    • R解法
    df <- df %>% 
      mutate(split = str_split(linestaion,'_'))
    
    pandas / R
    • python解法
    df.shape[1]
    # 54
    
    • R解法
    length(df)
    # [1] 54
    

    • python解法
    df[df['industryField'].str.startswith('数据')]
    
    • R解法
    df[grep("^数据", df$industryField),]
    

    以salary score 和 positionID制作数据透视

    • python解法
    pd.pivot_table(df,values=["salary","score"],index="positionId")
    
    • R解法
    df <- df %>% 
      group_by(positionId) %>% 
      dplyr::summarise(salary = mean(salary),
                score = mean(score)) %>% 
      as.data.frame(.) 
    rownames(df) <- NULL
    tibble::column_to_rownames(df,var='positionId')
    
    pandas / R
    • python解法
    df[["salary","score"]].agg([np.sum,np.mean,np.min])
    
    • R解法
    res <- df %>% 
      select(salary,score) %>% 
      pivot_longer(c(salary,score),names_to = 'type',values_to = 'value') %>% 
      group_by(type) %>% 
      summarise(sum = sum(value),mean = mean(value),min = min(value))
    
    rownames(res) <- NULL
    
    res %>% 
      column_to_rownames('type') %>% 
      t(.)
    
    pandas / R
    • python解法
    df.agg({"salary":np.sum,"score":np.mean})
    
    • R解法
    df %>% 
      summarise(salary_sum = sum(salary),
                score_mean = mean(score))
    
    pandas / R
    • python解法
    df[['district','salary']].groupby(by='district').mean().sort_values(
        'salary',ascending=False).head(1)
    
    • R解法
    df %>% 
      group_by(district) %>% 
      summarise(avg = mean(salary)) %>% 
      arrange(desc(avg)) %>% 
      filter(row_number() == 1)
    
    pandas / R

    以上就是R语言和python共同挑战数据分析120题的全部内容

    相关文章

      网友评论

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

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