pandas教程06---DataFrame的实用操作

欢迎关注公众号【Python开发实战】,免费领取Python学习电子书!

工具-pandas

pandas库提供了高性能、易于使用的数据结构和数据分析工具。其主要数据结构是DataFrame,可以将DataFrame看做内存中的二维表格,如带有列名和行标签的电子表格。许多在Excel中可用的功能都可以通过编程实现,例如创建数据透视表、基于其他列计算新列的值、绘制图形等。还可以按照列的值对行进行分组,或者像SQL中那样连接表格。pandas也擅长处理时间序列。

但是介绍pandas之前,需要有numpy的基础,如果还不熟悉numpy,可以查看numpy快速入门教程

导入pandas

import pandas as pd

Dataframe对象

一个DataFrame对象表示一个电子表格,带有单元格值、列名和行索引标签。可以定义表达式基于其他列计算列的值、创建数据透视表、按行分组、绘制图形等。可以将DataFrame视为Series的字典。

自动对齐

grades_array = np.array([[8, 8, 9], [10, 9, 9], [4, 8, 2], [9, 10, 10]])
grades = pd.DataFrame(grades_array, columns=['sep', 'oct', 'nov'], index=['alice', 'bob', 'charles', 'darwin'])
grades

输出:

image-20220411213053539

和Series相似,当操作多个DataFrame时,pandas会根据行索引标签自动对齐,但是也会按列名对齐。现在创建一个DataFrame,在10-12月每个人的奖励积分。

bonus_array = np.array([[0, np.nan, 2], [np.nan, 1, 0], [0, 1, 0], [3, 3, 0]])
bonus_points = pd.DataFrame(bonus_array, columns=['oct', 'nov', 'dec'], index=['bob', 'colin', 'darwin', 'charles'])
bonus_points

输出:

image-20220411213402765

bonus_points + grades

输出:

image-20220411213426026

处理缺失值

在处理真实数据时,处理缺失数据是一项常见的任务。pandas提供了一些处理缺失数据的工具。

现在解决上面的问题,例如可以决定将缺失值设置为0,而不是NaN。可以使用fillna()方法,将所有的NaN值替换为任意值。

(bonus_points + grades).fillna(0)

输出:

image-20220413134819334

但是,在9月份将分数设为0有点不公平。或许应该确定缺失的分数就是缺失的分数,但是缺失的积分奖励应该被0替代。

fixed_bonus_points = bonus_points.fillna(0)    # 将积分奖励的缺失值替换为0
fixed_bonus_points.insert(0, 'sep', 0)   # 添加九月份一列
fixed_bonus_points.loc['alice'] = 0   # 添加alice一行
grades + fixed_bonus_points

输出:

image-20220413134843319

这样处理之后结果就好得多,虽然制造了一些数据,但是没有太不公平。

处理缺失值的另一种方法是插值。现在我们在看一下积分奖励DataFrame。

bonus_points

输出:

image-20220413134921162

现在调用interpolate()方法,默认情况下,它是垂直插值,即axis=0,现在设置水平插值,axis=1。

bonus_points.interpolate(axis=1)

输出:

image-20220413134945595

水平插值处理缺失值时,bob在10月份为0分,12月份为2分,对11月份插值时会得到平均值1分。colin在11月份为1分,但是不知道他在九月份的奖励分,所以无法插值,这就是为什么插值后10月份仍然缺少一个值。为了解决这个问题,可以在插值之前将9月份的奖励分设置为0。

better_bouns_points = bonus_points.copy()
better_bouns_points.insert(0, 'sep', 0)
better_bouns_points.loc['alice'] = 0
better_bouns_points = better_bouns_points.interpolate(axis=1)
better_bouns_points

输出:

image-20220413135024626

现在有合理的奖励积分了,再看看最后的成绩。

better_bouns_points + grades

输出:

image-20220413135041040

上面的结果中,9月份出现了右边,这有点不太满意。这是因为我们添加的DataFrame没有完全相同的列, 即grades缺少dec列,所以pandas按字母顺序排序了列。解决这个问题,只需要在添加之前,添加缺少的列即可,即在grades中添加dec列。

grades['dec'] = np.nan
final_grades = better_bouns_points + grades
final_grades

输出:

image-20220413135108239

对于12月份列和colin行, 可以考虑使用dropna()方法,去除充满NaN的行或列。

final_grades_clean = final_grades.dropna(axis=0, how='all')   # 删除整行均为NaN的行
final_grades_clean

输出:

image-20220413140112365

final_grades_clean = final_grades_clean.dropna(axis=1, how='all')  # 删除整列均为NaN的列
final_grades_clean

输出:

image-20220413140142164

使用groupby分组聚合

与SQL语言相似,pandas允许将数据进行分组,以便在每组上进行运算。

首先,在final_grades添加一些关于每个人的额外数据,以便可以对他们分组。然后,再回到final_grades,看一下NaN值是如何处理的。

final_grades['hobby'] = ['Biking', 'Dancing', np.nan, 'Dancing', 'Biking']
final_grades

输出:

image-20220413140209718

现在,按hobby将DataFrame进行分组。

grouped_grades = final_grades.groupby(by='hobby')
grouped_grades

输出:

<pandas.core.groupby.groupby.DataFrameGroupBy object at 0x0000000007EE2588>

按hobby进行分组后,计算每个hobby的平均值。

grouped_grades.mean()

输出:

image-20220413140245854

根据上面的结果,在计算平均值时,NaN值被跳过了。

数据透视表

pandas支持类似电子表格的数据透视表, 可以快速汇总数据。

现在在bonus_poins的基础上创建一个新的DataFrame,来介绍数据透视表。

bonus_points

输出:

image-20220413140339288

more_grades = final_grades_clean.stack().reset_index()
more_grades.columns = ['name', 'month', 'grade']
more_grades['bonus'] = [np.nan, np.nan, np.nan, 0, np.nan, 2, 3, 3, 0, 0, 1, 0]
more_grades

输出:

image-20220413140405753

对上面的DataFrame调用pandas的pivot_table()函数,要求按name列进行分组。默认情况下,pivot_table()函数计算每个数值列的平均值。

pd.pivot_table(more_grades, index='name')

输出:

image-20220413140507423

可以通过设置aggfunc参数来更改聚合函数,还可以指定要聚合哪些列的值。

pd.pivot_table(more_grades, index='name', aggfunc=np.max, values=['grade', 'bonus'])

输出:

image-20220413140537166

还可以指定要横向聚合的列,并通过设置margins=True来计算每行和每列的总平均值。

pd.pivot_table(more_grades, index='name', values='grade', columns='month', margins=True)

输出:

image-20220413140557374

还可以指定多个索引或列名,pandas将创建多级索引。

pd.pivot_table(more_grades, index=('name', 'month'), margins=True)

输出:

image-20220413140622476

预览函数

在处理大型DataFrame时,快速了解其内容非常有用。pandas提供了一些可以预览DataFrame的函数。

先创建一个包含数值、缺失值和文本值的大型DataFrame。

much_data = np.fromfunction(lambda x, y: (x+y*y)%17*11, (10000, 26))
large_df = pd.DataFrame(much_data, columns=list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'))
large_df[large_df % 16 == 0] = np.nan
large_df.insert(3, 'some_text', 'Blala')
large_df

输出:10000×27 大小的DataFrame,由于数据量大这里不做显示。

方法head()默认查看前5行,可以修改要查看的行数。

large_df.head()

输出:

image-20220413141110689

large_df.head(3)

输出:

image-20220413141148860

方法tail()默认查看后5行,也可以修改要查看的行数。

large_df.tail(2)

输出:

image-20220413141209030

方法info()是返回每一列内容的概况。

large_df.info()

输出:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10000 entries, 0 to 9999
Data columns (total 27 columns):
A            8823 non-null float64
B            8824 non-null float64
C            8824 non-null float64
some_text    10000 non-null object
D            8824 non-null float64
E            8822 non-null float64
F            8824 non-null float64
G            8824 non-null float64
H            8822 non-null float64
I            8823 non-null float64
J            8823 non-null float64
K            8822 non-null float64
L            8824 non-null float64
M            8824 non-null float64
N            8822 non-null float64
O            8824 non-null float64
P            8824 non-null float64
Q            8824 non-null float64
R            8823 non-null float64
S            8824 non-null float64
T            8824 non-null float64
U            8824 non-null float64
V            8822 non-null float64
W            8824 non-null float64
X            8824 non-null float64
Y            8822 non-null float64
Z            8823 non-null float64
dtypes: float64(26), object(1)
memory usage: 2.1+ MB

describe()方法可以很好地概述每列上的主要聚合值。

  • count:非空值(非NaN)的数量。
  • mean:非空值的平均值。
  • std:非空值的标准差。
  • min:非空值的最小值。
  • 25%、50%、75%:非空值的第25、50、75个百分位值。
  • max:非空值的最大值。
large_df.describe()

输出(部分显示):

image-20220413141243137

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凯旋.Lau

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值