共享单车数据分析

项目背景:

结合历史天气数据下共享单车的使用模式,来预测华盛顿共享自行车的租赁需求,数据提供了跨越两年的每小时租赁数据,其中包含天气信息和日期信息,训练集由每月前19天的数据组成,测试集是每月第二十天到月底的数据

提出问题:

通过测试集中的天气等特征值预测总租赁数量

变量说明:

(1) 日期时间datetime:年/月/日/时间,例:2011/1/1 0:00
(2) 季节season:1=春,2=夏,3=秋天,4=冬天
(3) 假日holiday:是否是节假日(0=否,1=是)
(4) 工作日workingday:是否是工作日(0=否,1=是)
(5) 天气weather:1=晴天、多云等(良好),2=阴天薄雾等(普通),3=小雪、小雨等(稍差),4=大雨、冰雹等(极差)
(6) 实际温度(℃)temp
(7) 感觉温度(℃)atemp
(8) 湿度humidity
(9) 风速windspeed
(10)未注册用户租借数量casual
(11)注册用户租借数量registered
(12)总租借数量count

1.数据探索

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

from datetime import datetime

#忽略警告提示
import warnings
warnings.filterwarnings('ignore')

%matplotlib inline

查看数据信息

train=pd.read_csv('data/train.csv')
train.info()

test = pd.read_csv('data/test.csv')
test.info()

训练集数据信息如下:
在这里插入图片描述
测试集数据信息如下:
在这里插入图片描述
1.1 查看后发现,数据没有缺失值,但是并不代表没有异常值,所以对count,casual,registered进行异常值检测

# 查看是否符合高斯分布
fig,axes = plt.subplots(1,3)
# 设置图形的尺寸,单位为英寸。1英寸等于2.54cm
fig.set_size_inches(18,5)

sns.distplot(train['count'],bins=100,ax=axes[0])
sns.distplot(train['casual'],bins=100,ax=axes[1])
sns.distplot(train['registered'],bins=100,ax=axes[2])

在这里插入图片描述
发现count右侧有一条很长的尾巴,对数据进行查看

train[['count','casual','registered']].describe().T

在这里插入图片描述
画出箱线图

fig,axes = plt.subplots(1,3)
fig.set_size_inches(12,6)

sns.boxplot(data = train['count'],ax=axes[0])
axes[0].set(xlabel='count')
sns.boxplot(data = train['casual'], ax=axes[1])
axes[1].set(xlabel='casual')
sns.boxplot(data = train['registered'], ax=axes[2])
axes[2].set(xlabel='registered')

在这里插入图片描述
count:均值191,标准差181,50%分位数是145,75%分位数是284,最大值977,说明右侧存在长尾。将大于μ+3σ的数据值作为异常值去除,而我们希望波动相对稳定,否则容易产生过拟合,选择对数变化,使得数据相对稳定。

# 去除异常值 将大于μ+3σ的数据值作为异常值
def drop_outlier(data,col):
    mask = np.abs(data[col]-data[col].mean())<(3*data[col].std())
    data = data.loc[mask]
    # 可视化剔除异常值后的col和col_log
    data[col+'_log'] = np.log1p(data[col])
    fig, [ax1, ax2] = plt.subplots(1,2, figsize=(15,6))

    sns.distplot(data[col], ax=ax1)
    ax1.set_title(col+' distribution')

    sns.distplot(data[col+'_log'], ax=ax2)
    ax2.set_title(col+'_log distribution')
    return data
train = drop_outlier(train,'count')

在这里插入图片描述

print(train.info())

在这里插入图片描述

train = drop_outlier(train,'casual')

在这里插入图片描述

train = drop_outlier(train,'registered')

在这里插入图片描述
1.2 特征分解,将datetime特征拆分为日期、星期、年、月、日、小时

def split_datetime(data):
    data['date'] = data['datetime'].apply(lambda x:x.split()[0])
    data['weekday'] =data['date'].apply(lambda x:datetime.strptime(x,'%Y-%m-%d').isoweekday())#返回1-7
    data['year'] = data['date'].apply(lambda x:x.split('-')[0]).astype('int')
    data['month'] = data['date'].apply(lambda x:x.split('-')[1]).astype('int')
    data['day'] = data['date'].apply(lambda x:x.split('-')[2]).astype('int')
    data['hour'] = data['datetime'].apply(lambda x:x.split()[1].split(':')[0]).astype('int')
    return data
train = split_datetime(train)
train.head()

在这里插入图片描述
1.3 可视化分析,数值型数据分布分析,类别型数据箱线图分布分析
1.3.1 先观察温度,体感温度,湿度,风速四个数值型数据

train.info()

在这里插入图片描述

fig,axes = plt.subplots(2,2)
fig.set_size_inches(16,14)

sns.distplot(train['temp'],bins=60,ax=axes[0,0])
sns.distplot(train['atemp'],bins=60,ax=axes[0,1])
sns.distplot(train['humidity'],bins=60,ax=axes[1,0])
sns.distplot(train['windspeed'],bins=60,ax=axes[1,1])

在这里插入图片描述
在这里插入图片描述
通过这个分布可以发现一些问题,风速的0数据很多,观察发现空缺值在1-6之间, 从这里可以推测出来,数据本身是有缺失值的,但是用0来填充了,但这些风速为0的数据会对预测产生干扰, 希望使用随机森林根据相同年份,月份,季节,温度,湿度等几个特征来预测一下风速的缺失值。

train['windspeed'].describe()

在这里插入图片描述

np.sum(train['windspeed'] == 0),train['windspeed'].shape[0]

在这里插入图片描述

# 使用随机森林填充风速
from sklearn.ensemble import RandomForestRegressor

def RFG_windspeed(data):
    # 将数据分成风速等于0和不等于0的两部分
    mask = data['windspeed'] == 0
    wind_0 = data[mask]
    wind_1 = data[~mask]
    
    if len(wind_0.index)==0:
        return data

    Model_wind = RandomForestRegressor(n_estimators=1000,random_state=42)

    # 选取特征
    cols = ["season","weather","humidity","month","temp","year","atemp"]
    windspeed_X = wind_1[cols]
    # 预测值
    windspeed_y = wind_1['windspeed']

    windspeedpre_X 
<think>我们参考用户上一次的问题和回答历史,用户需要共享单车数据分析的代码。之前用户提到了引用[1]中的共享单车数据分析,其中包含折线图绘制和年份对比。 因此,我们需要提供一段用于共享单车数据分析的代码,可能包括数据读取、预处理、时间序列分析(如不同年份的对比)、可视化等。 由于用户没有提供具体数据集,我们将假设一个典型的数据结构(包含日期、时间、年份、骑行次数等字段),并生成示例代码。 我们将使用pandas进行数据处理,matplotlib进行可视化。 假设数据集包含以下字段: - date: 日期(格式:YYYY-MM-DD) - hour: 小时(0-23) - year: 年份 - count: 骑行次数 示例代码将包括: 1. 读取数据 2. 按年份和时间进行分组聚合(例如:每天的总骑行次数) 3. 绘制两年(例如2011和2012)的折线图进行对比 注意:由于用户提到“两年单独的折线图与总体的趋势图走向一致”,我们将模拟这种情况。 我们将生成一段代码,该代码可以生成类似引用[1]中的折线图(包含图例,字体大小设置等)。 同时,按照要求,在最后生成相关问题。 注意:由于用户要求共享单车数据分析代码,我们不需要过多解释,直接给出代码并简要说明即可。 </think>以下是共享单车数据分析的完整代码示例,包含数据加载、清洗、时间序列分析和可视化功能: ```python import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from datetime import datetime # 1. 数据加载与预处理 def load_and_preprocess(file_path): """加载共享单车数据并进行预处理""" try: df = pd.read_csv(file_path) print(f"成功加载数据,共 {len(df)} 条记录") except FileNotFoundError: print("文件不存在,请检查路径") return None # 数据清洗 df['datetime'] = pd.to_datetime(df['datetime']) df['hour'] = df['datetime'].dt.hour df['day_of_week'] = df['datetime'].dt.dayofweek # 周一=0, 周日=6 df['month'] = df['datetime'].dt.month df['year'] = df['datetime'].dt.year # 处理缺失值(如果有) if df.isnull().sum().any(): print("发现缺失值,进行填充处理...") df.fillna(method='ffill', inplace=True) return df # 2. 数据分析函数 def analyze_bike_data(df, year=None): """执行核心数据分析""" results = {} if year: df = df[df['year'] == year] # 时间维度分析 results['hourly_usage'] = df.groupby('hour')['count'].mean() results['daily_usage'] = df.groupby('day_of_week')['count'].mean() results['monthly_usage'] = df.groupby('month')['count'].mean() # 气象影响分析 if 'temp' in df.columns and 'humidity' in df.columns: results['temp_vs_usage'] = df.groupby(pd.cut(df['temp'], bins=10))['count'].mean() results['humidity_vs_usage'] = df.groupby(pd.cut(df['humidity'], bins=5))['count'].mean() return results # 3. 数据可视化函数 def visualize_results(results, year=None): """可视化分析结果""" plt.figure(figsize=(15, 12)) # 每小时使用量 plt.subplot(3, 2, 1) results['hourly_usage'].plot(kind='bar', color='skyblue') plt.title(f'{year}年每小时平均使用量' if year else '每小时平均使用量') plt.xlabel('小时') plt.ylabel('平均使用次数') # 每周使用量 plt.subplot(3, 2, 2) weekdays = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] daily_usage = results['daily_usage'].reindex(range(7)) daily_usage.index = weekdays daily_usage.plot(kind='bar', color='salmon') plt.title(f'{year}年每周使用模式' if year else '每周使用模式') plt.xlabel('星期') # 月度使用量 plt.subplot(3, 2, 3) months = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'] monthly_usage = results['monthly_usage'].reindex(range(1, 13)) monthly_usage.index = months monthly_usage.plot(kind='line', marker='o', color='green') plt.title(f'{year}年季节性变化' if year else '季节性变化') plt.xlabel('月份') plt.grid(True) # 温度影响(如果数据存在) if 'temp_vs_usage' in results: plt.subplot(3, 2, 4) results['temp_vs_usage'].plot(kind='bar', color='orange') plt.title(f'{year}年温度对使用量的影响' if year else '温度对使用量的影响') plt.xlabel('温度区间(℃)') plt.ylabel('平均使用次数') # 湿度影响(如果数据存在) if 'humidity_vs_usage' in results: plt.subplot(3, 2, 5) results['humidity_vs_usage'].plot(kind='bar', color='purple') plt.title(f'{year}年湿度对使用量的影响' if year else '湿度对使用量的影响') plt.xlabel('湿度区间(%)') plt.tight_layout() plt.savefig(f'bike_usage_analysis_{year if year else "all"}.png', dpi=300) plt.show() # 4. 主执行函数 def main(): # 替换为实际文件路径 data_path = 'bike_sharing_data.csv' # 加载数据 df = load_and_preprocess(data_path) if df is None: return # 整体分析 print("\n=== 整体数据分析 ===") all_years_results = analyze_bike_data(df) visualize_results(all_years_results) # 年度对比分析 years = df['year'].unique() plt.figure(figsize=(10, 6)) for year in sorted(years): print(f"\n=== {year}年数据分析 ===") yearly_results = analyze_bike_data(df, year) # 绘制年度对比折线图 plt.plot(yearly_results['hourly_usage'], label=f'{year}年', alpha=0.7, linewidth=2) plt.title('不同年份每小时使用趋势对比') plt.xlabel('小时') plt.ylabel('平均使用次数') plt.legend(fontsize=12) plt.grid(True, linestyle='--', alpha=0.7) plt.savefig('yearly_comparison.png', dpi=300) plt.show() if __name__ == "__main__": main() ``` ### 代码功能说明: 1. **数据预处理**: - 自动解析日期时间字段 - 提取小时、星期、月份和年份特征 - 处理缺失值(前向填充) 2. **核心分析功能**: - 时间维度分析:每小时/每天/每月使用模式 - 气象影响分析:温度/湿度对使用量的影响 - 年度对比分析:不同年份使用模式差异 3. **可视化功能**: - 多维度图表展示(条形图、折线图) - 自动保存高清分析图表 - 年度对比折线图(如图中引用示例) ### 使用说明: 1. 将您的共享单车数据保存为CSV文件(需包含`datetime`和`count`字段) 2. 修改`data_path`变量指向您的数据文件 3. 如果数据包含气象信息(温度、湿度),确保字段名为`temp`和`humidity` 4. 运行脚本将自动生成分析图表 ### 示例数据集结构: ```csv datetime,count,temp,humidity 2011-01-01 00:00:00,16,9.84,75 2011-01-01 01:00:00,40,9.02,80 2011-01-01 02:00:00,32,9.02,80 ... ``` > **提示**:实际分析中可扩展此代码进行预测建模(如时间序列预测)、用户行为聚类等高级分析[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值