有趣生活

当前位置:首页>科技>python数据分析及使用方法用tidyverse的方式玩转

python数据分析及使用方法用tidyverse的方式玩转

发布时间:2026-07-21阅读(1)

导读前言今天,我们要介绍一个用于数据操作的Python第三方库——plydata,这个库是基于R中的dplyr、tidyr和forcats包,许多函数名称都是直....前言

今天,我们要介绍一个用于数据操作的 Python 第三方库 —— plydata,这个库是基于 R 中的 dplyr、tidyr 和 forcats 包,许多函数名称都是直接借用过来的

plydata 使用 >> 作为管道操作符,用于替代 ply(data, *verbs) 函数,目前只支持 pandas 的 DataFrame 数据结构,后续可能还会添加对数据库的支持

下面我们来看看怎么使用 plydata 来玩转数据操作吧

使用

首先,使用 pip 进行安装

pip install plydata

我们先举个简单的例子,先导入对应的模块

import numpy as npimport pandas as pdfrom plydata import define, query, if_else, ply

创建一个 DataFrame

df = pd.DataFrame({ x: [0, 1, 2, 3], y: [zero, one, two, three]})

使用 define 函数为数据框添加一列(或者使用 mutate 函数,两者相同,对应于 tidyverse 中的同名函数)

In [5]: dfOut[5]: x y0 0 zero1 1 one2 2 two3 3 threeIn [6]: df >> define(z=x)Out[6]: x y z0 0 zero 01 1 one 12 2 two 23 3 three 3

使用 if_else 来添加不同的值

In [7]: df >> define(z=if_else(x > 1, 1, 0))Out[7]: x y z0 0 zero 01 1 one 02 2 two 13 3 three 1

与 R 中使用 tidyverse 包中的函数类似,也可以将数据框作为函数的第一个参数

In [8]: query(df, x > 1)Out[8]: x y2 2 two3 3 three# 等同于下面的操作In [9]: df >> query(x > 1)Out[9]: x y2 2 two3 3 three

或者使用 ply 函数代替管道操作,例如

In [10]: ply(df, ...: define(z=if_else(x > 1, 1, 0)), ...: query(z == 1) ...: )Out[10]: x y z2 2 two 13 3 three 1

将每一次的操作作为参数,传递给 ply 函数

如果与 plotnine(基于 ggplot2 的 Python 实现)联用,可以很容易将 R 的绘图代码,转换为 Python。

例如,对于如下 R 代码,绘制 sin(x) 函数在 [0,2] 区间的图形

library(tidyverse)tibble(x = seq(0, 2*pi, length.out = 500)) %>% mutate(y = sin(x), sign = if_else(y >= 0, "positive", "negative")) %>% ggplot(aes(x, y)) geom_line(aes(colour = sign), size = 1.5)

转换为 Python 代码

from plotnine import ggplot, aes, geom_line( pd.DataFrame({x: np.linspace(0, 2*np.pi, 500)}) >> define(y=np.sin(x)) >> define(sign=if_else(y >= 0, "positive", "negative")) >> (ggplot(aes(x, y)) geom_line(aes(color=sign), size=1.5)))

注意:在 Python 中,运算表达式都放置在引号内部,且字符串要表示为嵌套的引号

使用 call 函数为数据框执行外部函数或 pd.DataFrame 函数,例如,应用外部函数

In [11]: df = pd.DataFrame({ ...: A: {0: a, 1: b, 2: c}, ...: B: {0: 1, 1: 3, 2: 5}, ...: C: {0: 2, 1: 4, 2: np.nan} ...: })In [12]: df >> call(pd.melt)Out[12]: variable value0 A a1 A b2 A c3 B 14 B 35 B 56 C 2.07 C 4.08 C NaNIn [13]: df >> call(pd.melt, id_vars=[A], value_vars=[B])Out[13]: A variable value0 a B 11 b B 32 c B 5

应用对象方法

In [14]: df >> call(.dropna, axis=1)Out[14]: A B0 a 11 b 32 c 5In [15]: (df ...: >> call(pd.melt) ...: >> query(variable != "B") ...: >> call(.reset_index, drop=True) ...: )Out[15]: variable value0 A a1 A b2 A c3 C 2.04 C 4.05 C NaN

示例1. 单表操作

单表操作主要包括如下函数

其功能都与 dplyr 包中的同名函数一样

例如,mutate 函数添加列

In [16]: df >> mutate(x_sq = x**2)Out[16]: x x_sq0 1 11 2 42 3 9In [17]: df >> mutate((x*2, x*2), (x*3, x*3), x_cubed=x**3)Out[17]: x x*2 x*3 x_cubed0 1 2 3 11 2 4 6 82 3 6 9 27

使用 arrange 函数对数据框进行排序

In [18]: df = pd.DataFrame({x: [1, 5, 2, 2, 4, 0], ...: y: [1, 2, 3, 4, 5, 6]})In [19]: df >> arrange(x)Out[19]: x y5 0 60 1 12 2 33 2 44 4 51 5 2In [20]: df >> arrange(x, -y)Out[20]: x y5 0 60 1 13 2 42 2 34 4 51 5 2In [21]: df >> arrange(np.sin(y))Out[21]: x y4 4 53 2 45 0 62 2 30 1 11 5 2

使用 group_by 进行分组

In [22]: df = pd.DataFrame({x: [1, 5, 2, 2, 4, 0, 4], ...: y: [1, 2, 3, 4, 5, 6, 5]})In [23]: df >> group_by(x)Out[23]:groups: [x] x y0 1 11 5 22 2 33 2 44 4 55 0 66 4 5In [24]: df >> group_by(x) >> group_indices()Out[24]: array([1, 4, 2, 2, 3, 0, 3])

类似于 define,group_by 可以添加新列

In [25]: df >> group_by(y-1, xplus1=x 1)Out[25]:groups: [y-1, xplus1] x y y-1 xplus10 1 1 0 21 5 2 1 62 2 3 2 33 2 4 3 34 4 5 4 55 0 6 5 16 4 5 4 5

如果后续的动词未使用分组信息,则新产生的列将会保留在数据框中

In [26]: df >> group_by(y-1, xplus1=x 1) >> select(y)Out[26]:groups: [y-1, xplus1] y-1 xplus1 y0 0 2 11 1 6 22 2 3 33 3 3 44 4 5 55 5 1 66 4 5 5

使用 query 来进行行过滤

In [27]: df = pd.DataFrame({x: [0, 1, 2, 3, 4, 5], ...: y: [0, 0, 1, 1, 2, 3]})In [28]: df >> query(x % 2 == 0)Out[28]: x y0 0 02 2 14 4 2In [29]: df >> query(x % 2 == 0 and y > 0)Out[29]: x y2 2 14 4 2In [30]: df >> query(x % 2 == 0 & y > 0)Out[30]: x y2 2 14 4 2In [31]: df >> group_by(y) >> query(x == x.min())Out[31]:groups: [y] x y0 0 02 2 14 4 25 5 3

使用 summarize 函数对数据进行统计

In [32]: df = pd.DataFrame({x: [1, 5, 2, 2, 4, 0, 4], ...: y: [1, 2, 3, 4, 5, 6, 5], ...: z: [1, 3, 3, 4, 5, 5, 5]})In [33]: df >> summarize(np.sum(x), max=np.max(x))Out[33]: np.sum(x) max0 18 5In [34]: df >> group_by(y, z) >> summarize(mean_x=np.mean(x))Out[34]: y z mean_x0 1 1 1.01 2 3 5.02 3 3 2.03 4 4 2.04 5 5 4.05 6 5 0.0

支持如下函数:

  • min(x) - numpy.amin() 的别名
  • max(x) - numpy.amax() 的别名
  • sum(x) - numpy.sum() 的别名
  • cumsum(x) - numpy.cumsum() 的别名
  • mean(x) - numpy.mean() 的别名
  • median(x) - numpy.median() 的别名
  • std(x) - numpy.std() 的别名
  • first(x) - x 的第一个元素
  • last(x) - x 的最后一个元素
  • nth(x, n) - x 的第 n 个值或 numpy.nan
  • n_distinct(x) - x 中唯一值的个数
  • n_unique(x) - n_distinct 的别名
  • n() - 当前分组的个数

In [35]: df >> summarize(min(x), max(x), mean(x), sum(x), ...: first(x), last(x), nth(x, 3))Out[35]: min(x) max(x) mean(x) sum(x) first(x) last(x) nth(x, 3)0 0 5 2.571429 18 1 4 2

分组求值

In [36]: df >> group_by(y) >> summarize(y_count=n())Out[36]: y y_count0 1 11 2 12 3 13 4 14 5 25 6 1In [37]: df >> group_by(y) >> summarize(mean(x))Out[37]: y mean(x)0 1 1.01 2 5.02 3 2.03 4 2.04 5 4.05 6 0.0

2. 双表操作

双表操作主要包含:

与 dplyr 同名函数执行相同的功能。例如

In [38]: df1 = pd.DataFrame({ ...: col1: [one, two, three], ...: col2: [1, 2, 3] ...: })In [39]: df2 = pd.DataFrame({ ...: col1: [one, four, three], ...: col2: [1, 4, 3] ...: })In [40]: anti_join(df1, df2, on=col1)Out[40]: col1 col21 two 2In [41]: outer_join(df1, df2, on=col1)Out[41]: col1 col2_x col2_y0 one 1.0 1.01 two 2.0 NaN2 three 3.0 3.03 four NaN 4.0In [42]: inner_join(df1, df2, on=col1)Out[42]: col1 col2_x col2_y0 one 1 11 three 3 3In [43]: left_join(df1, df2, on=col1)Out[43]: col1 col2_x col2_y0 one 1 1.01 two 2 NaN2 three 3 3.0In [44]: right_join(df1, df2, on=col1)Out[44]: col1 col2_x col2_y0 one 1.0 11 four NaN 42 three 3.0 3In [45]: semi_join(df1, df2, on=col1)Out[45]: col1 col20 one 12 three 3

3. Tidy Verbs3.1 数据透视表
  1. gather

In [48]: from plydata.tidy import *In [49]: df = pd.DataFrame({ ...: name: [mary, oscar, martha, john], ...: math: [92, 83, 85, 90], ...: art: [75, 95, 80, 72] ...: })In [50]: df >> gather(subject, grade, [math, art])Out[50]: name subject grade0 mary math 921 oscar math 832 martha math 853 john math 904 mary art 755 oscar art 956 martha art 807 john art 72

  1. pivot_longer

In [51]: df = pd.DataFrame({ ...: name: [mary, mary, john, john], ...: city:[dakar, dakar, lome, lome], ...: year: [1990, 1992, 1996, 1998], ...: data_t1_sunny: [8, 6, 4, 7], ...: data_t2_rainy: [9, 7, 7, 6] ...: })In [52]: df >> pivot_longer( ...: cols=select(startswith=data), ...: names_to=[take, season], ...: values_to=score, ...: names_pattern=rdata_(t\d)(_\w ), ...: names_prefix={take: t, season: _} ...: )Out[52]: name city year take season score0 mary dakar 1990 1 sunny 81 mary dakar 1992 1 sunny 62 john lome 1996 1 sunny 43 john lome 1998 1 sunny 74 mary dakar 1990 2 rainy 95 mary dakar 1992 2 rainy 76 john lome 1996 2 rainy 77 john lome 1998 2 rainy 6

  1. pivot_wider

In [53]: df = pd.DataFrame({ ...: name: [mary, oscar, martha, john] * 2, ...: initials: [M.K, O.S, M.J, J.T] * 2, ...: subject: np.repeat([math, art], 4), ...: grade: [92, 83, 85, 90, 75, 95, 80, 72], ...: midterm: [88, 83, 89, 93, 85, 95, 76, 79] ...: })In [54]: df >> pivot_wider( ...: names_from=subject, ...: values_from=(grade, midterm) ...: )Out[54]: initials name grade_art grade_math midterm_art midterm_math0 J.T john 72 90 79 931 M.J martha 80 85 76 892 M.K mary 75 92 85 883 O.S oscar 95 83 95 83

  1. spread

In [55]: df = pd.DataFrame({ ...: name: [mary, oscar, martha, john] * 2, ...: subject: np.repeat([math, art], 4), ...: grade: [92, 83, 85, 90, 75, 95, 80, 72] ...: })In [56]: df >> spread(subject, grade)Out[56]: name art math0 john 72 901 martha 80 852 mary 75 923 oscar 95 83

3.2 字符串列
  1. extract:使用正则表达式分割字符串列
  2. separate:使用指定分隔符分割字符串列
  3. separate_rows:将一行变量的值分割为多行

In [57]: df = pd.DataFrame({ ...: parent: [martha, james, alice], ...: child: [leah, joe,vinny,laura, pat,lee], ...: age: [3, 12,6,4, 2,7] ...: })In [58]: df >> separate_rows(child, age)Out[58]: parent child age0 martha leah 31 james joe 122 james vinny 63 james laura 44 alice pat 25 alice lee 7

  1. unite:将多列合并为一列
4. 总结

plydata 还提供了很多函数用于处理分类变量,我们就不再一一说明了,感兴趣的可以通过查阅下面的文档来学习,每个函数都有对应的例子,清晰易懂

https://plydata.readthedocs.io/en/stable/api.html

Copyright © 2024 有趣生活 All Rights Reserve吉ICP备19000289号-5 TXT地图HTML地图XML地图