美文网首页
22 比较共享单车各类用户的平均骑行时间趋势

22 比较共享单车各类用户的平均骑行时间趋势

作者: 夏威夷的芒果 | 来源:发表于2018-07-17 19:26 被阅读24次

    数据源:https://video.mugglecode.com/data.zip

    需要了解哪些 明确任务

    数据过滤

    典型的数组+布尔数组的过滤

    看看下面的数据,既然要区分会员与否,不是只读取一列数据了,要读取两列数据的。


    image.png

    看还是要去掉里面的双引号。


    用文本编辑器打开数据

    如何制作bool向量?广播

    左侧一列是矢量,但是必要判断的量是一个标量,矢量和标量是没法直接比较的,但是Numpy里面的广播,可以自动把标量扩展成与待比较的矢量相同尺寸的参考矢量。


    image.png
    import os
    import numpy as np
    import matplotlib.pyplot as plt
    
    data_path = '/Users/miraco/PycharmProjects/DataMining/bikeshare'
    data_filenames = ['2017-q1_trip_history_data.csv', '2017-q2_trip_history_data.csv',
                      '2017-q3_trip_history_data.csv','2017-q4_trip_history_data.csv']
    
    def collect_and_process_data():   #数据获取和数据处理
        clean_data_arr_list = []
        for data_filename in data_filenames:
            data_file = os.path.join(data_path, data_filename)
            print(data_file)
            # 读数据默认读取是浮点数, 但这个csv数据类型,各种还有年月日的,保险起见都用字符串类型
            data_arr = np.loadtxt(data_file, delimiter=',', dtype='str', skiprows=1)  # 读进来的数据
            data_arr = np.core.defchararray.replace(data_arr,'"','') #去双引号
            clean_data_arr_list.append(data_arr)
        return clean_data_arr_list
    
    
    def get_mean_duration_by_type(data_arr_list, member_type):  #数据分析
        #如何制作bool向量?广播
        mean_duration_list = []
        for data_arr in data_arr_list:
            #最后一列是身份数据,所以以布尔判断取之
            bool_arr = (data_arr[:,-1] == member_type )
            filtered_data_arr = data_arr[bool_arr]   #布尔过滤
            mean_duration = np.mean(filtered_data_arr[:,0].astype('float')/1000/60) #字符转浮点
            mean_duration_list.append(mean_duration)
        return mean_duration_list
    
    def save_and_show_results(member_mean_duration_list,casual_mean_duration_list):
        #信息输出
        for idx in range(len(member_mean_duration_list)):  #其实就是四个季度
            member_mean_duration = member_mean_duration_list[idx]
            casual_mean_duration = casual_mean_duration_list[idx]
            print('第{}个季度,会员的平均骑行时长是{:.2f}分钟,非会员的平均骑行时长是{:.2f}分钟'.format(
                idx + 1 ,member_mean_duration, casual_mean_duration
            ))
        #分析结果保存
        #构造多维数组
        mean_duration_arr = np.array([member_mean_duration_list,casual_mean_duration_list]).transpose()
        #上面的这个,这是两行四列的数据,要是想存四行两列,需要转置,这时候用transpose()方法
        # 数据存储默认科学计数法,如果不愿意,那么fmt可以指定小数点几位
        np.savetxt(
            './bikeshare/mean_duration.csv',  #保存路径/文件名
            mean_duration_arr,     #保存哪个变量
            delimiter=',',           #变量之间以什么分隔
            header = 'Member mean duration, Casual mean duration',  #首行类名标注
            fmt = '%.4f',   # 数据存储默认科学计数法,如不愿意,fmt可指定小数点后几位
            comments= ''  #存储时,第一个类名会默认带个井号#,一般都不要井号,想指定为空时候就这么干
        )
        #可视化
        plt.figure()
        #bar是柱状图,plot是折线图
        plt.plot(member_mean_duration_list, color = 'g', linestyle = '-', marker = 'o',label = 'Member')  #画第一条线
        plt.plot(casual_mean_duration_list, color = 'r', linestyle = '--', marker = '*',label = 'Casual')   #画第二条线
        plt.title('Member VS Casual')  #题目
        plt.xticks(range(0,4),['1st', '2nd', '3rd', '4th'], rotation = 45)
        #上一行的意思是对x刻度进行指定,这里是留四个位置,后面填位置上写的东西
        #刻度特别长的时候,可以旋转避免文字相碰,可选参数rotation
        plt.xlabel('Quarter')  #x标签名
        plt.ylabel('Mean Duration (min)')   #y标签名
        plt.legend(loc = 'best')  #图例位置自动选择最优位置摆放
        plt.tight_layout()  #保持紧凑,避免下方变体文字越界
        plt.savefig('./bikeshare/duration_trend.png')
        #保存操作一定要在show之前,不然保存下来的将会是一个图片
        plt.show()
    
    
    
    def main():
        #数据获取和处理
        clean_data_arr_list = collect_and_process_data()
    
        #数据分析
        #会员
        member_mean_duration_list = get_mean_duration_by_type(clean_data_arr_list,'Member')
        #非会员
        casual_mean_duration_list = get_mean_duration_by_type(clean_data_arr_list, 'Casual')
    
        save_and_show_results(member_mean_duration_list,casual_mean_duration_list)
    
    
    
    if __name__ == '__main__':
        main()
    
    • 得到的图


    • 存储的表


      存储的表
    知识点

    需要注意哪些问题?

    • 存储格式
    np.savetxt(
            './bikeshare/mean_duration.csv',  #保存路径/文件名
            mean_duration_arr,     #保存哪个变量
            delimiter=',',           #变量之间以什么分隔
            header = 'Member mean duration, Casual mean duration',  #首行类名标注
            fmt = '%.4f',   # 数据存储默认科学计数法,如不愿意,fmt可指定小数点后几位
            comments= ''  #存储时,第一个类名会默认带个井号#,一般都不要井号,想指定为空时候就这么干
        )
    
    如果不标注fmt = '%.4f'就会出现如图数据形式,二者这个图是没加transpose的,明显应该转置一下
    如果不指定comments= '' ,那么存储时,第一个类名会默认带个井号#

    练习

    题目描述:按月份统计每月气温的最大值、最小值及平均值。

    题目要求:使用NumPy中布尔型数组进行数据过滤

    数据文件:

    • 数据源下载地址:https://video.mugglecode.com/temp2.csv。temp2.csv 中包含了2018年1-3月北京的气温(每日的最低温度)。每行记录为1天的数据。
    • 共2列数据,第1列month为月份,第2列temperature为摄氏温度

    问题拆解提示:

    1. 如何使用NumPy读取csv数据文件?
    2. 如何构造布尔型数组?
    3. 如何使用布尔型数组进行数据过滤?
    4. 如何统计最大值、最小值及平均值?
    • 问题解决提示:
    1. 利用NumPy模块中的loadtxt()(https://docs.scipy.org/doc/numpy/reference/generated/numpy.loadtxt.html)方法读取csv数据文件,需要指定2个参数的值
    • delimiter=',':csv文件的数据分隔符,默认为空格;
    • skiprows=1:跳过第一行(表头),默认为0,表示数据包含第一行;
    • 可以不指定dtype参数。由于csv中的数据全部可以转换为float类型,所以dtype使用默认的float即可;
    1. 使用一列数据和月份值做比较,构造布尔型数组
    2. 将布尔型数组放在向量的索引操作中;
    3. 直接使用NumPy提供的max()(https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.max.html)、min()(https://docs.scipy.org/doc/numpy/reference/generated/numpy.minimum.html)及mean()(https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.mean.html)可以获取一组数据的最大值、最小值及平均值。

    画图相关的知识点、图例等等选项参数一览

    矩阵拼接

    参考答案

    #https://video.mugglecode.com/temp2.csv
    
    import os
    import numpy as np
    import matplotlib.pyplot as plt
    
    file = '/Users/miraco/PycharmProjects/DataMining/bikeshare/temp2.csv'
    data = np.loadtxt(file, delimiter=',', dtype='str', skiprows=1)
    data_pure_str = np.core.defchararray.replace(data,'"','')
    data_num = data_pure_str.astype('float')
    
    def filter_by_month(data,month):    #按月过滤的函数
        return data[data[:,0] ==  month]
    
    jan_temp = filter_by_month(data_num, 1)
    feb_temp = filter_by_month(data_num, 2)
    mar_temp = filter_by_month(data_num, 3)
    
    #最低温
    jan_min = np.min(jan_temp[:,1])
    feb_min = np.min(feb_temp[:,1])
    mar_min = np.min(mar_temp[:,1])
    min_temp = [jan_min] + [feb_min] + [mar_min]
    
    #最高温
    jan_max = np.max(jan_temp[:,1])
    feb_max = np.max(feb_temp[:,1])
    mar_max = np.max(mar_temp[:,1])
    max_temp = [jan_max] + [feb_max] + [mar_max]
    
    #平均温
    jan_mean = np.mean(jan_temp[:,1])
    feb_mean = np.mean(feb_temp[:,1])
    mar_mean = np.mean(mar_temp[:,1])
    mean_temp = [jan_mean] + [feb_mean] + [mar_mean]
    
    #存文件
    np.savetxt(
        './bikeshare/3_month_variation_of_temperature.csv',
        np.hstack(([[1],[2],[3]] ,np.array([min_temp,max_temp ,mean_temp]).transpose())),
        delimiter=',',
        comments = '',
        header = 'Month,Min Temperature,Max Temprature,Mean Temperature',
        fmt = '%.2f'
    )
    #图
    plt.figure()
    plt.plot(min_temp,color ='g', linestyle = '-',marker = 'o',label = 'Min Temperature')
    plt.plot(max_temp,color ='r', linestyle = '--',marker = '*',label = 'Max Temperature')
    plt.plot(mean_temp,color ='b', linestyle = '-.',marker = '^',label = 'Mean Temperature')
    
    plt.xticks(range(0,3),['Jan','Feb','Mar'],rotation = 45)
    plt.title('Variation of temperatures in 3 months')
    plt.legend(loc = 'best')
    plt.xlabel('Month')
    plt.ylabel('Temperatures')
    plt.tight_layout()
    plt.savefig('./bikeshare/3_month_variation_of_temperature.png')   #存图
    plt.show()
    
    
    运行得到的图 存表数据

    相关文章

      网友评论

          本文标题:22 比较共享单车各类用户的平均骑行时间趋势

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