探索11个实用却可能被忽略的Pandas函数。
微信搜索关注《Python学研大本营》,加入读者群,分享更多精彩
使用Stable Diffusion生成的图像
7.ordered CategoricalDtype
说到数据类型,你已经知道可以使用category
数据类型,以更高性能的方式存储重复的字符串值,也就是说,可以节省大量的内存。
要把一个字符串列转换成一个分类列,可以使用下面的代码片段:
df["x"].astype("category")
为了更进一步,还可以使用有序的分类数据类型。例如,想象一下正在为一家服装公司工作,有5种尺寸的商品。
为了在保持尺寸逻辑的同时对该信息进行编码,可以创建一个自定义的CategoricalDtype
数据类型,其分类值的顺序是正确的,并指定ordered
参数为True
。最后,可以使用熟悉的astype
方法将一个列转换成新创建的数据类型。
from pandas.api.types import CategoricalDtype
df = pd.DataFrame({
"size": ["XL", "S", "M", "XS", "L"],
"sales": [50, 10, 20, 90, 100]}
)
categories = CategoricalDtype(
["XS", "S", "M", "L", "XL"],
ordered=True
)
df["size"] = df["size"].astype(categories)
df
使用有序分类数据类型的好处是什么?例如,可以很容易地按该类别排序,并获得相关的排序,而不是使用字符串名称的字母顺序。
df.sort_values(by="size")
此外,还可以使用有序的分类数据类型进行更相关的过滤。在下面的代码片段中,我们希望只保留大于M
的尺寸。
df[df["size"] > "M"]
8.SparseDtype
已经讨论了使用分类数据类型作为优化Pandas使用的内存的潜在方式。另一种方法是利用稀疏数据类型。
例如,可以有主要包含零的数字列。可以通过将这种列视为稀疏来大大减少内存消耗。准确地说,大部分数值不需要是零,它可以用NaN或其他任何数值表示。只要这个单一的值是经常重复的。
在底层工作方式下,稀疏对象的压缩方式是任何与特定值(0、NaN或任何其他占多数的值)匹配的数据都被省略。为了节省空间,这样的压缩值实际上并不存储在数组中。
生成一个其中大多数的值都等于0的大规模DataFrame。
df = pd.DataFrame(np.random.randint(0, 100, size=(10000000, 5)))
df[df <= 90] = 0
然后,定义一个辅助函数,用于评估DataFrame的内存消耗:
def memory_usage(df):
return(round(df.memory_usage(deep=True).sum() / 1024 ** 2, 2))
初始消耗为:
memory_usage(df)
可以尝试将数字类型向下转换为最小的可用类型——uint8
。
df_1 = df.astype("uint8")
memory_usage(df_1)
这样做可以减少88%的内存使用量。作为下一步,我们将使用稀疏数据类型。
df_2 = df.astype(pd.SparseDtype("uint8", 0))
memory_usage(df_2)
通过利用稀疏数据类型,比之前的解决方案(使用uint8
数据类型)减少了55%,与最初的DataFrame相比,减少了94%。
9.crosstab
聚合是一个很好的方法,可以将大量的数据汇总成一个全面的、信息丰富的摘要。crosstab
是用于汇总数据的Pandas函数之一。默认情况下,它计算DataFrame的列中某些数值组合的出现次数。
首先,生成一个包含一些分类值和数值的DataFrame。
N = 1000
df = pd.DataFrame({
"group": np.random.choice(["AA", "BB"], N),
"region": np.random.choice(["a", "b", "c"], N, p=[0.5, 0.3, 0.2]),
"category": np.random.choice(["x", "y", "z"], N, p=[0.3, 0.3, 0.4]),
"sales": np.random.normal(1000, 50, N)
})
df
使用最简单的crosstab
函数可以生成以下区域和类别列之间的数值统计表。
pd.crosstab(df['region'], df['category'])
可以更进一步,一次对多个类别进行汇总。
pd.crosstab(df['region'], [df["group"], df['category']])
AAx | AAy | AAz | BBx | BBy | BBz | |
---|---|---|---|---|---|---|
a | 79 | 70 | 115 | 63 | 88 | 96 |
b | 48 | 40 | 50 | 49 | 34 | 69 |
c | 25 | 32 | 39 | 31 | 28 | 44 |
还可以通过使用margins
参数显示行和列的总数。
pd.crosstab(df['region'], df['category'], margins=True)
如果对计数不感兴趣,而是对分布感兴趣,可以使用normalize
参数来显示百分比。
pd.crosstab(df['region'], df['category'], normalize=True)
也可以把margins
和normalize
参数结合起来,这样就可以跨行或跨列进行归一化处理。要做到这一点,应该向normalize
参数传递index
或columns
,而margins
则设置为True
。
最后,还可以使用crosstab
来汇总数值数据。使用下面的代码片段,计算出各地区和类别的平均销售额。
pd.crosstab(
df["region"],
df["category"],
values = df["sales"],
aggfunc = "mean"
).round(2)
10.swaplevel
人们不喜欢用MultiIndex
工作,因为它总是会让人头疼。然而,swaplevel
是可以使MultiIndex
的工作更容易的方法之一。它的作用是简单地交换MultiIndex
中索引的位置。
重新使用crosstab
示例中的一些代码,并生成一个简单的聚合表。
df_agg = pd.crosstab([df["group"], df['category']], df['region'])
df_agg
a | b | c | |
---|---|---|---|
('AA','x') | 79 | 48 | 25 |
('AA','y') | 70 | 40 | 32 |
('AA','z') | 115 | 50 | 39 |
('BB','x') | 63 | 49 | 31 |
('BB','y') | 88 | 34 | 28 |
('BB','z') | 96 | 69 | 44 |
如果想切换索引的位置,可以使用该swaplevels
方法。
a | b | c | |
---|---|---|---|
('x','AA') | 79 | 48 | 25 |
('y','AA') | 70 | 40 | 32 |
('z','AA') | 115 | 50 | 39 |
('x','BB') | 63 | 49 | 31 |
('y','BB') | 88 | 34 | 28 |
('z','BB') | 96 | 69 | 44 |
对于更复杂的情况,可以提供想要交换的索引的整数位置,以及想要交换索引的axis
(行或列)。
当然,这只是一个简化的示例,可以通过改变crosstab
函数中的列的顺序来交换索引。
11. resample
resample
是一个非常有用的方法,可以用来对时间序列数据进行分组和聚合。该方法工作的一个条件是DataFrame必须有一个DateTimeIndex
。
首先,创建一个样本DataFrame,其在2023年的每一天都有一个值。
df = pd.DataFrame(
index=pd.date_range("2023-01-01", "2023-12-31")
)
df["value"] = list(range(len(df)))
df
然后,可以将数据汇总到每周的频率,并计算每个bin
内有多少个观察值:
df.resample("W").count().head()
或者可以很容易地将每个月的数值相加(以月初为索引)。
df.resample("MS").sum()
默认情况下,resample
是在范围的左侧关闭的。使用上表,这意味着它对从“2023-01-01” 开始直到“2023-02-01”之前最后一刻的所有数值进行求和(不包括该数值)。可以通过使用closed
参数来改变这种行为。
另外,resample
在用于聚合的规则方面非常灵活,可以对任意的频率进行重新取样。例如,可以使用下面的代码片段轻松地聚合到每4个月:
df.resample("4M").max()
根据经验,在处理时间部分时,rule
参数的灵活性也真正发挥了作用,例如,每小时、每分钟或每秒钟登记的数据。
总结
希望你通过阅读这篇文章,你能发现Pandas的一些新功能,使数据分析更加轻松。
推荐书单
《Pandas1.x实例精解》
《Pandas1.x实例精解》详细阐述了与Pandas相关的基本解决方案,主要包括Pandas基础,DataFrame基本操作,创建和保留DataFrame,开始数据分析,探索性数据分析,选择数据子集,过滤行,对齐索引,分组以进行聚合、过滤和转换,将数据重组为规整形式,组合Pandas对象,时间序列分析,使用Matplotlib、Pandas和Seaborn进行可视化,调试和测试等内容。此外,该书还提供了相应的示例、代码,以帮助读者进一步理解相关方案的实现过程。 《Pandas1.x实例精解》适合作为高等院校计算机及相关专业的教材和教学参考书,也可作为相关开发人员的自学用书和参考手册。
精彩回顾
《事半功倍,用 Python 和 Beautiful Soup 编写网络爬虫》
《精美绝伦,用 Stable Diffusion 和 Dreambooth 为宠物创建艺术照(下)》
《精美绝伦,用 Stable Diffusion 和 Dreambooth 为宠物创建艺术照(上)》
微信搜索关注《Python学研大本营》,加入读者群
访问【IT今日热榜】,发现每日技术热点