当前位置:首页 > 技术 > 正文内容

DataFrame数据分析入门

访客 技术 2026年5月26日 3

一、日期时间处理

1. 字符串转日期类型

使用 to_datetime() 方法将字符串字段转换为日期类型:

import pandas as pd

# 创建示例数据
sales_df = pd.DataFrame({
    "sales": [100, 200, 300, 400, 500],
    "order_date": ["2019-01-01", "2019-01-02", "2019-01-03", "2019-01-04", "2019-01-05"]
})

print("转换前:")
print(sales_df)
print(sales_df.dtypes)

# 将order_date列转换为日期格式
sales_df["order_date"] = pd.to_datetime(sales_df["order_date"])

print("\n转换后:")
print(sales_df)
print(sales_df.dtypes)

输出结果:

转换前:
   sales order_date
0    100  2019-01-01
1    200  2019-01-02
2    300  2019-01-03
3    400  2019-01-04
4    500  2019-01-05
sales            int64
order_date       str
dtype: object

转换后:
   sales order_date
0    100 2019-01-01
1    200 2019-01-02
2    300 2019-01-03
3    400 2019-01-04
4    500 2019-01-05
sales                    int64
order_date    datetime64[us]
dtype: object

2. 日期属性访问器 Series.dt

通过 Series.dt 访问器可以获取日期数据的各种属性:

import pandas as pd

# 创建示例数据
date_df = pd.DataFrame({
    "value": [100, 200, 300, 400],
    "date_str": ["2025-01-06", "2032-09-08", "2024-09-08", "2002-09-08"]
})

# 转换为日期格式
date_df["date"] = pd.to_datetime(date_df["date_str"])

# 提取年月日
date_df["year"] = date_df["date"].dt.year
date_df["month"] = date_df["date"].dt.month
date_df["day"] = date_df["date"].dt.day

# 获取星期几
date_df["weekday"] = date_df["date"].dt.day_name()

# 获取季度
date_df["quarter"] = date_df["date"].dt.quarter

# 判断是否月末/年初
date_df["is_month_end"] = date_df["date"].dt.is_month_end
date_df["is_month_start"] = date_df["date"].dt.is_month_start
date_df["is_year_end"] = date_df["date"].dt.is_year_end
date_df["is_year_start"] = date_df["date"].dt.is_year_start

print(date_df)

输出结果:

   value    date_str       date  year  month  day   weekday  quarter  is_month_end  is_month_start  is_year_end  is_year_start
0    100  2025-01-06 2025-01-06  2025      1    6    Monday         1         False          False          False          False
1    200  2032-09-08 2032-09-08  2032      9    8  Wednesday         3         False          False          False          False
2    300  2024-09-08 2024-09-08  2024      9    8    Sunday         3         False          False          False          False
3    400  2002-09-08 2002-09-08   2002      9    8    Sunday         3         False          False          False          False

3. 获取统计周期 to_period()

to_period() 方法的 freq 参数用于指定时间周期频率:

  • D: 按天周期
  • W: 按周周期
  • M: 按月周期
  • Q: 按季度周期
  • Y: 按年周期
# 添加各种统计周期列
date_df["year_period"] = date_df["date"].dt.to_period(freq="Y")
date_df["month_period"] = date_df["date"].dt.to_period(freq="M")
date_df["quarter_period"] = date_df["date"].dt.to_period(freq="Q")
date_df["week_period"] = date_df["date"].dt.to_period(freq="W")
date_df["day_period"] = date_df["date"].dt.to_period(freq="D")

print(date_df[["date", "year_period", "month_period", "quarter_period", "week_period"]])

输出结果:

         date year_period month_period quarter_period    week_period
0 2025-01-06        2025       2025-01         2025Q1  2025-01-06/2025-01-12
1 2032-09-08        2032       2032-09         2032Q3  2032-09-06/2032-09-12
2 2024-09-08        2024       2024-09         2024Q3  2024-09-02/2024-09-08
3 2002-09-08        2002       2002-09         2002Q3  2002-09-02/2002-09-08

二、DataFrame 数据分析基础

1. 加载数据集

import pandas as pd

# 加载CSV数据
df = pd.read_csv("data/weather.csv")

# 查看数据基本信息
print("数据形状:", df.shape)
print("\n数据类型:")
print(df.dtypes)
print("\n列名:")
print(df.columns.tolist())
print("\n数据类型:")
print(type(df))

数据集包含6列:日期(date)、降水量(precipitation)、最高温度(temp_max)、最低温度(temp_min)、风速(wind)、天气状况(weather),共1461条记录。

2. 查看数据

# 查看前5行
print(df.head())

# 查看后5行
print(df.tail())

# 获取单列数据(返回Series)
date_series = df["date"]
print(type(date_series))

# 获取单列数据(返回DataFrame)
date_df = df[["date"]]
print(type(date_df))

# 获取多列数据
multi_col_df = df[["date", "temp_max", "temp_min"]]

# 按行标签获取数据
print(df.loc[0])
print(df.loc[0:5])

# 按行索引获取数据
print(df.iloc[1])
print(df.iloc[0:5])

# 获取特定行列数据
print(df.loc[0:5, "date"])
print(df.loc[0:5, ["date", "temp_max"]])
print(df.iloc[0:5, 0:3])

3. 分组聚合计算

# 按月分组,统计最高温度和最低温度的平均值
df["date"] = pd.to_datetime(df["date"])
df["month"] = df["date"].dt.to_period(freq="M")

# 分组聚合
monthly_temp = df.groupby("month")[["temp_max", "temp_min"]].mean()
print(monthly_temp)

# 统计每月不同天气的种类数
weather_count = df.groupby("month")["weather"].nunique()
print(weather_count)

# 统计每月下雨天的数量
rainy_days = df[df["weather"] == "rain"].groupby("month").size()
print(rainy_days)

三、实战练习

练习1:数据加载与查看

import pandas as pd

# 加载数据
df = pd.read_csv("data/weather.csv")

# 查看数据形状
print(df.shape)

# 查看前10行
print(df.head(10))

# 查看后10行
print(df.tail(10))

# 查看数据类型
print(df.dtypes)

# 查看列名
print(df.columns.tolist())

练习2:日期时间转换

import pandas as pd

df = pd.read_csv("data/weather.csv")

# 转换日期列
df["date"] = pd.to_datetime(df["date"])

# 创建新列存储日期属性
df["year"] = df["date"].dt.year
df["month"] = df["date"].dt.month
df["day"] = df["date"].dt.day
df["weekday"] = df["date"].dt.day_name()
df["quarter"] = df["date"].dt.quarter

print(df.head())
print(df.dtypes)

练习3:数据筛选

# 筛选下雨天的数据
rainy = df[df["weather"] == "rain"]

# 筛选2012年的数据
year_2012 = df[df["date"].dt.year == 2012]

# 筛选夏季数据(6-8月)
summer = df[(df["month"] >= 6) & (df["month"] <= 8)]

# 筛选最高温度超过25度的数据
hot_days = df[df["temp_max"] > 25]

# 筛选下雨且风速大于5的数据
rainy_windy = df[(df["weather"] == "rain") & (df["wind"] > 5)]

print(f"下雨天数量: {len(rainy)}")
print(f"2012年数据量: {len(year_2012)}")
print(f"夏季数据量: {len(summer)}")
print(f"高温天数: {len(hot_days)}")
print(f"下雨刮风天数: {len(rainy_windy)}")

练习4:年度分组统计

# 统计每年天气类型总数
yearly_weather = df.groupby("year")["weather"].value_counts()
print("每年天气类型统计:")
print(yearly_weather)

# 统计每年天气种类数
weather_types = df.groupby("year")["weather"].nunique()
print("\n每年天气种类数:")
print(weather_types)

# 计算每年平均最高温、最低温
yearly_temp = df.groupby("year")[["temp_max", "temp_min"]].agg(["mean", "max", "min"])
print("\n每年温度统计:")
print(yearly_temp)

# 统计每年总降水量
yearly_rain = df.groupby("year")["precipitation"].sum()
print("\n每年降水量:")
print(yearly_rain)

# 统计每年下雨天数
rainy_days_by_year = df[df["weather"] == "rain"].groupby("year").size()
print("\n每年下雨天数:")
print(rainy_days_by_year)

# 找出下雨最多的年份
max_rain_year = rainy_days_by_year.idxmax()
max_rain_count = rainy_days_by_year.max()
print(f"\n下雨最多的年份: {max_rain_year},下雨天数: {max_rain_count}")

练习5:月度分组统计

# 统计每月天气类型
monthly_weather = df.groupby("month")["weather"].value_counts()

# 每月平均温度
monthly_temp = df.groupby("month")[["temp_max", "temp_min"]].mean()
print("每月平均温度:")
print(monthly_temp)

# 每月总降水量
monthly_precipitation = df.groupby("month")["precipitation"].sum()
print("\n每月降水量:")
print(monthly_precipitation)

# 每月下雨天数
rainy_days_by_month = df[df["weather"] == "rain"].groupby("month").size()

# 找出下雨最多的月份
max_rain_month = rainy_days_by_month.idxmax()
max_rain = rainy_days_by_month.max()
print(f"\n下雨最多的月份: {max_rain_month}月,下雨天数: {max_rain}天")

groupby() 多列选择语法:

场景 语法 说明
选择单列 df.groupby("分组")["列名"] 返回 SeriesGroupBy
选择多列 df.groupby("分组")[["列1", "列2"]] 返回 DataFrameGroupBy,注意使用双中括号
聚合单列 .agg(["mean", "max"]) 返回多级索引的 Series
聚合多列 .agg(["mean", "max", "min"]) 返回多级列的 DataFrame

四、数据可视化

使用 plot() 方法绘制图表,默认生成折线图:

# 按月统计温度均值并绘制折线图
df.groupby("month")[["temp_max", "temp_min"]].mean().plot()

五、常用统计方法

import pandas as pd

df = pd.read_csv("data/weather.csv")

# 查看常用统计信息
stats = df.describe()
print(stats)

# 转置显示
print(stats.T)

# 统计所有列(包括字符串列)
print(df.describe(include="all"))

# 只统计数值列
print(df.describe(include=["number"]))

六、常用排序方法

  • nlargest(n, columns): 获取最大的n行
  • nsmallest(n, columns): 获取最小的n行
  • sort_values(columns, ascending): 按列排序
  • drop_duplicates(subset): 按列去重
import pandas as pd

df = pd.read_csv("data/weather.csv")

# 找出最高温度最高的30天
hottest_days = df.nlargest(30, "temp_max")
print(hottest_days)

# 从最高温度最高的30天中找出最低温度最低的5天
coldest_of_hot = df.nlargest(30, "temp_max").nsmallest(5, "temp_min")
print(coldest_of_hot)

# 转换日期格式
df["date"] = pd.to_datetime(df["date"])
df["year"] = df["date"].dt.year

# 按年份去重,获取每年最高温度
df_sorted = df.sort_values("temp_max", ascending=False)
yearly_max = df_sorted.drop_duplicates(subset="year")
print(yearly_max[["date", "temp_max", "year"]])

七、综合案例:员工数据分析

使用员工数据集,包含:员工ID、姓名、邮箱、电话、工种、薪资、佣金比例、经理ID、部门ID 等字段。

import pandas as pd

# 加载数据
employees = pd.read_csv("data/employees.csv")

# 查看数据基本信息
print(employees.head())
print(employees.info())
print(employees.describe())
print(f"数据形状: {employees.shape}")

# 找出薪资最高的员工
top_salary = employees.nlargest(1, "salary")
print("\n薪资最高员工:")
print(top_salary)

# 找出薪资最低的员工
low_salary = employees.nsmallest(1, "salary")
print("\n薪资最低员工:")
print(low_salary)

# 找出薪资最高的10名员工
top_10 = employees.nlargest(10, "salary")
print("\n薪资Top10:")
print(top_10[["first_name", "last_name", "salary"]])

# 查看所有部门ID
print("\n部门ID列表:")
print(employees["department_id"].unique())

# 统计每个部门员工数
dept_count = employees.groupby("department_id")["employee_id"].count()
print("\n各部门员工数:")
print(dept_count)

# 统计薪资分布
print(f"\n平均薪资: {employees['salary'].mean()}")
print(f"中位薪资: {employees['salary'].median()}")
print(f"薪资标准差: {employees['salary'].std()}")

# 找出平均薪资最高的部门
avg_salary_by_dept = employees.groupby("department_id")["salary"].mean()
top_dept = avg_salary_by_dept.nlargest(1)
print("\n平均薪资最高部门:")
print(top_dept)

# 绘制各部门平均薪资柱状图
employees.groupby("department_id")["salary"].mean().plot(kind="bar")

通过以上示例,可以掌握 pandas 的数据加载、清洗、转换、筛选、分组聚合、可视化等核心操作,为数据分析工作打下坚实基础。

标签: PandasPython

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。