数据源: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为摄氏温度
问题拆解提示:
- 如何使用NumPy读取csv数据文件?
- 如何构造布尔型数组?
- 如何使用布尔型数组进行数据过滤?
- 如何统计最大值、最小值及平均值?
- 问题解决提示:
- 利用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即可;
- 使用一列数据和月份值做比较,构造布尔型数组
- 将布尔型数组放在向量的索引操作中;
- 直接使用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()
运行得到的图
存表数据
网友评论