数据采集与数据分析代码实操

0 阅读6分钟

数据采集是指识别数据源、收集原始数据并将其传输或存储到可以处理的地方的过程。它是整个数据价值链的起点。

数据分析是指对采集到的数据进行清理、转换、建模、探索和解释,以发现有用的信息、得出结论并支持决策的过程。它是将原始数据转化为洞察力的关键步骤。

“数据采集”和“数据分析”是现代数据驱动决策的核心环节,它们紧密相连,共同构成了从原始信息到有价值见解的完整链条。

a6.png

下面我将通过实际代码示例,展示数据采集(API获取、网页抓取)和数据分析(数据清洗、探索性分析、可视化)的全流程操作。

环境准备

# 安装必要库
pip install requests beautifulsoup4 pandas numpy matplotlib seaborn scikit-learn

一、数据采集代码示例

1、通过API获取数据(以天气数据为例)

import requests
import pandas as pd
​
def get_weather_data(api_key, city="Beijing", days=7):
    """从WeatherAPI获取天气数据"""
    url = f"http://api.weatherapi.com/v1/forecast.json?key={api_key}&q={city}&days={days}"
    
    try:
        response = requests.get(url)
        response.raise_for_status()  # 检查请求是否成功
        data = response.json()
        
        # 提取所需数据
        weather_data = []
        for day in data['forecast']['forecastday']:
            date = day['date']
            max_temp = day['day']['maxtemp_c']
            min_temp = day['day']['mintemp_c']
            avg_temp = day['day']['avgtemp_c']
            condition = day['day']['condition']['text']
            rain_chance = day['day']['daily_chance_of_rain']
            
            weather_data.append({
                'date': date,
                'max_temp': max_temp,
                'min_temp': min_temp,
                'avg_temp': avg_temp,
                'condition': condition,
                'rain_chance': rain_chance
            })
        
        return pd.DataFrame(weather_data)
    
    except requests.exceptions.RequestException as e:
        print(f"请求错误: {e}")
        return None# 使用示例 (需替换为实际API密钥)
# api_key = "YOUR_API_KEY"
# weather_df = get_weather_data(api_key)
# weather_df.to_csv('weather_data.csv', index=False)

2、网页抓取示例(电影Top250)

from bs4 import BeautifulSoup
import requests
import pandas as pd
import re
import time
​
def scrape_douban_top250():
    """抓取豆瓣电影Top250数据"""
    base_url = "https://movie.douban.com/top250?start="
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
    }
    
    movies = []
    
    for start in range(0, 250, 25):
        url = base_url + str(start)
        response = requests.get(url, headers=headers)
        soup = BeautifulSoup(response.text, 'html.parser')
        
        for item in soup.find_all('div', class_='item'):
            title = item.find('span', class_='title').text
            year = re.search(r'((\d{4}))', item.find('div', class_='bd').p.text).group(1)
            rating = float(item.find('span', class_='rating_num').text)
            votes = item.find('div', class_='star').find_all('span')[-1].text[:-3]
            quote = item.find('span', class_='inq').text if item.find('span', class_='inq') else ""
            
            movies.append({
                'title': title,
                'year': int(year),
                'rating': rating,
                'votes': int(votes),
                'quote': quote
            })
        
        time.sleep(1)  # 礼貌性延迟
    
    return pd.DataFrame(movies)
​
# 执行抓取
# movie_df = scrape_douban_top250()
# movie_df.to_csv('douban_top250.csv', index=False)

二、数据分析代码示例

1、数据清洗与预处理

import pandas as pd
import numpy as np
​
# 加载数据
df = pd.read_csv('douban_top250.csv')
​
# 1. 处理缺失值
print("缺失值统计:")
print(df.isnull().sum())
​
# 对于quote列的缺失值,填充为"无"
df['quote'] = df['quote'].fillna('无')
​
# 2. 异常值处理
# 检查评分范围 (豆瓣评分范围0-10)
print("\n评分统计:")
print(df['rating'].describe())
​
# 3. 数据类型转换
df['year'] = df['year'].astype(int)
​
# 4. 创建新特征 - 年代分类
bins = [0, 1960, 1980, 1990, 2000, 2010, 2020, np.inf]
labels = ['1960前', '60-70年代', '80年代', '90年代', '00年代', '10年代', '20年代']
df['decade'] = pd.cut(df['year'], bins=bins, labels=labels)
​
# 5. 数据抽样展示
print("\n清洗后数据示例:")
print(df.sample(5))

2、探索性数据分析(EDA)

import matplotlib.pyplot as plt
import seaborn as sns
​
# 设置可视化风格
sns.set(style="whitegrid")
plt.figure(figsize=(12, 8))
​
# 1. 评分分布
plt.subplot(2, 2, 1)
sns.histplot(df['rating'], bins=15, kde=True, color='skyblue')
plt.title('电影评分分布')
plt.xlabel('评分')
​
# 2. 不同年代电影数量
plt.subplot(2, 2, 2)
decade_counts = df['decade'].value_counts().sort_index()
sns.barplot(x=decade_counts.index, y=decade_counts.values, palette="viridis")
plt.title('不同年代电影数量')
plt.xlabel('年代')
plt.ylabel('数量')
plt.xticks(rotation=45)
​
# 3. 评分与投票数关系
plt.subplot(2, 2, 3)
sns.scatterplot(data=df, x='rating', y='votes', hue='decade', palette='Set2', s=100)
plt.title('评分与投票数关系')
plt.xlabel('评分')
plt.ylabel('投票数')
​
# 4. 各年代平均评分
plt.subplot(2, 2, 4)
decade_rating = df.groupby('decade')['rating'].mean().sort_index()
sns.barplot(x=decade_rating.index, y=decade_rating.values, palette="rocket")
plt.title('各年代平均评分')
plt.xlabel('年代')
plt.ylabel('平均评分')
plt.xticks(rotation=45)
​
plt.tight_layout()
plt.savefig('eda_visualization.png', dpi=300)
plt.show()

3、高级分析:评分预测模型

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error, r2_score
​
# 特征工程
df['title_length'] = df['title'].apply(len)
df['has_quote'] = df['quote'].apply(lambda x: 1 if x != '无' else 0)
​
# 准备数据
X = df[['year', 'votes', 'title_length', 'has_quote']]
y = df['rating']
​
# 划分训练测试集
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)
​
# 创建并训练模型
model = RandomForestRegressor(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
​
# 预测与评估
y_pred = model.predict(X_test)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
​
print(f"模型评估结果:")
print(f"平均绝对误差(MAE): {mae:.4f}")
print(f"R²分数: {r2:.4f}")
​
# 特征重要性分析
feature_importances = pd.Series(model.feature_importances_, index=X.columns)
plt.figure(figsize=(10, 6))
feature_importances.sort_values().plot(kind='barh', color='teal')
plt.title('特征重要性分析')
plt.xlabel('重要性分数')
plt.tight_layout()
plt.savefig('feature_importance.png', dpi=300)
plt.show()
​
# 实际值与预测值对比
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_pred, alpha=0.6, color='purple')
plt.plot([y.min(), y.max()], [y.min(), y.max()], 'k--', lw=2)
plt.xlabel('实际评分')
plt.ylabel('预测评分')
plt.title('实际评分 vs 预测评分')
plt.grid(True)
plt.tight_layout()
plt.savefig('prediction_comparison.png', dpi=300)
plt.show()

4、文本分析(电影短评)

from wordcloud import WordCloud
from collections import Counter
import jieba
​
# 生成词云
text = ' '.join(df['quote'].tolist())
​
# 中文分词
word_list = jieba.cut(text)
word_count = Counter(word_list)
​
# 过滤停用词和单字
stopwords = ['的', '了', '是', '我', '你', '他', '这', '那', '就', '也', '在', '和', '与']
filtered_words = {word: count for word, count in word_count.items() 
                 if len(word) > 1 and word not in stopwords and not word.isdigit()}
​
# 创建词云
wordcloud = WordCloud(
    font_path='simhei.ttf',  # 中文字体文件
    width=800, 
    height=600,
    background_color='white',
    max_words=200
).generate_from_frequencies(filtered_words)
​
plt.figure(figsize=(12, 8))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.title('豆瓣Top250电影短评词云')
plt.savefig('wordcloud.png', dpi=300)
plt.show()

三、完整流程整合

# 完整的数据采集与分析流程
def full_data_pipeline():
    # 1. 数据采集
    print("开始数据采集...")
    movie_df = scrape_douban_top250()
    movie_df.to_csv('douban_top250.csv', index=False)
    print(f"采集完成,共获取{movie_df.shape[0]}条数据")
    
    # 2. 数据清洗
    print("\n开始数据清洗...")
    # 添加清洗步骤...
    
    # 3. 数据分析
    print("\n开始数据分析...")
    # 添加分析步骤...
    
    # 4. 可视化
    print("\n生成可视化图表...")
    # 添加可视化步骤...
    
    print("\n全流程完成!结果已保存到本地")
​
# 执行完整流程
# full_data_pipeline()

这个完整的代码示例涵盖了从数据采集到分析的全流程,你可以根据实际需求调整各部分内容。对于大规模数据项目,可以考虑使用Scrapy(爬虫)、Apache Spark(大数据处理)和TensorFlow/PyTorch(深度学习)等更专业的工具。

理解这两个环节及其紧密联系,对于任何希望利用数据驱动发展的个人或组织都至关重要。数据采集为你铺好道路,数据分析则为你点亮明灯,共同引领你走向更明智的决策。

大家想了解数据采集或数据分析的某个具体方面吗?比如某种采集技术、某种分析方法、特定行业的应用案例,或者相关的工具推荐?可以留言讨论,有空的时候我可以出个教程。