在学习 Python 数据分析与可视化的过程中,我完成了一个让我印象深刻的项目 —— 分析本地共享单车使用的数据。这个项目不仅让我巩固了所学知识,还让我在实践中发现并解决了许多问题。下面,我将详细拆解这个项目的步骤,并分享我的经验与心得。
一、项目背景与目标
共享单车在城市中已经非常普及,它为人们的短距离出行提供了极大的便利。我从本地共享单车公司获取了一年的使用数据,包括用户信息、骑行时间、起点与终点位置等。我的目标是通过数据分析与可视化,揭示共享单车的使用规律,例如高峰时段、热门骑行区域、不同用户群体的使用习惯等,为共享单车公司的运营决策提供参考。
二、数据预处理
(一)数据清洗
拿到数据后,我首先用 pandas 的 read_csv()
函数将其导入到 Python 中。数据中存在一些缺失值,比如部分用户的年龄信息缺失。我通过分析发现,缺失值的比例并不高,所以我选择直接删除这些包含缺失值的行。代码如下:
import pandas as pd
data = pd.read_csv('shared_bike_data.csv')
data.dropna(inplace=True)
在删除缺失值后,我还检查了数据的类型是否正确。例如,骑行时间本应该是时间戳格式,但导入后却被识别为字符串。我使用 pd.to_datetime()
函数将其转换为正确的时间格式:
data['ride_time'] = pd.to_datetime(data['ride_time'])
(二)数据筛选
为了更专注于分析,我筛选出了特定时间段(例如工作日)的数据。我先提取出骑行时间中的星期信息,然后根据星期筛选数据:
data['weekday'] = data['ride_time'].dt.weekday
workday_data = data[data['weekday'] < 5]
三、数据分析
(一)高峰时段分析
我想要找出共享单车的高峰使用时段。我先提取出骑行时间中的小时信息,然后统计每个小时内的骑行次数。代码如下:
data['hour'] = data['ride_time'].dt.hour
hourly_counts = data['hour'].value_counts().sort_index()
通过绘制柱状图,我清晰地看到了高峰时段。我使用 matplotlib 来绘制:
import matplotlib.pyplot as plt
plt.bar(hourly_counts.index, hourly_counts.values)
plt.xlabel('Hour')
plt.ylabel('Number of Rides')
plt.title('Hourly Ride Counts')
plt.show()
从图中可以看出,早高峰在 7 - 9 点,晚高峰在 17 - 19 点,这与人们的日常通勤时间相符。
(二)热门骑行区域分析
数据中包含了起点与终点的经纬度信息。我使用 seaborn 的 heatmap
函数来绘制热门骑行区域的热力图。首先,我需要将起点与终点的经纬度分别提取出来,并统计每个区域的骑行次数。然后,我将这些数据转换为适合绘制热力图的格式:
import seaborn as sns
start_points = data[['start_latitude', 'start_longitude']]
end_points = data[['end_latitude', 'end_longitude']]
all_points = pd.concat([start_points, end_points])
heatmap_data = all_points.groupby(['start_latitude', 'start_longitude']).size().unstack()
sns.heatmap(heatmap_data, cmap='hot')
plt.title('Popular Ride Areas')
plt.show()
热力图显示了城市中几个热门骑行区域,这些区域大多是商业中心和居民区附近。
四、数据可视化进阶
(一)用户群体分析
数据中包含用户的性别和年龄信息。我想要分析不同性别和年龄段的用户使用共享单车的习惯差异。我先将用户按性别和年龄段分组,然后统计每个组的骑行次数。代码如下:
data['age_group'] = pd.cut(data['age'], bins=[18, 30, 40, 50, 60, 70, 80])
grouped_data = data.groupby(['gender', 'age_group']).size().unstack()
为了更直观地展示这些数据,我使用了 seaborn 的 heatmap
函数绘制堆叠柱状图:
sns.heatmap(grouped_data, cmap='viridis')
plt.xlabel('Age Group')
plt.ylabel('Gender')
plt.title('Ride Counts by Gender and Age Group')
plt.show()
从图中可以看出,男性用户在各个年龄段的骑行次数都略高于女性用户,而且 30 - 40 偲年龄段的用户骑行次数最多。
(二)骑行时长分析
我想要分析骑行时长的分布情况。我先计算出每次骑行的时长,然后绘制直方图。代码如下:
data['ride_duration'] = (data['end_time'] - data['start_time']).dt.total_seconds() / 60
plt.hist(data['ride_duration'], bins=30, edgecolor='black')
plt.xlabel('Ride Duration (minutes)')
plt.ylabel('Number of Rides')
plt.title('Ride Duration Distribution')
plt.show()
直方图显示,大部分骑行时长在 5 - 15 分钟之间,这表明共享单车主要用于短距离出行。
五、遇到的问题与解决方法
(一)数据量过大导致内存不足
在处理数据时,我发现数据量过大,导致内存不足。我尝试了以下几种方法来解决这个问题:
在未来的学习中,我计划学习更高级的数据分析方法,例如机器学习和深度学习,并将其应用到实际项目中。同时,我也希望能够与其他数据分析师交流经验,共同进步。
如果你对这个项目感兴趣,或者有任何问题和建议,欢迎在评论区留言。让我们一起在 Python 数据分析与可视化的道路上不断前行!
这个项目让我对 Python 数据分析与可视化有了更深入的理解,也让我更有信心去挑战更复杂的项目。希望我的经验能对大家有所帮助。
-
分块读取数据:我使用 pandas 的
read_csv()
函数的chunksize
参数,将数据分块读取。这样可以避免一次性将整个数据集加载到内存中。代码如下:chunk_size = 10000 chunks = pd.read_csv('shared_bike_data.csv', chunksize=chunk_size) for chunk in chunks: # 处理每个数据块
优化数据类型:我检查了数据的类型,发现有些列的数据类型可以优化。例如,将一些整数列从
int64
转换为int32
,这样可以节省内存。代码如下:data['age'] = data['age'].astype('int32')
(二)绘图速度慢
在绘制热力图时,我发现绘图速度很慢。我尝试了以下方法来提高绘图速度:
-
降低数据分辨率:我将经纬度数据进行了离散化处理,降低了数据的分辨率。这样可以减少绘图时的数据点数量,提高绘图速度。代码如下:
data['start_latitude'] = data['start_latitude'].round(2) data['start_longitude'] = data['start_longitude'].round(2)
使用更快的绘图库:我尝试了使用 Plotly 来绘制热力图,发现 Plotly 的绘图速度比 seaborn 更快。代码如下:
import plotly.express as px fig = px.density_mapbox(data, lat='start_latitude', lon='start_longitude', z='ride_count', radius=10, center=dict(lat=39.9, lon=116.4), zoom=10, mapbox_style='stamen-terrain') fig.show()
六、总结与心得
通过这个项目,我不仅巩固了 Python 数据分析与可视化的知识,还学会了如何在实际项目中解决遇到的问题。我总结了以下几点心得:
-
数据预处理的重要性:数据预处理是数据分析的基础,只有数据准确、干净,才能进行有效的分析。
-
灵活运用可视化工具:不同的可视化工具适用于不同的场景,要根据实际需求选择合适的工具。
-
优化代码性能:在处理大数据时,要注意优化代码性能,避免内存不足和绘图速度慢等问题。