在类别内计算:Python中等同于R的ddply的是什么?

12 投票
3 回答
4460 浏览
提问于 2025-04-17 04:17

我有一些R语言的代码需要转到Python上。不过,R语言里的神奇数据框(data.frame)和ddply让我很难找到在Python中实现的好方法。

示例数据(R):

x <- data.frame(d=c(1,1,1,2,2,2),c=c(rep(c('a','b','c'),2)),v=1:6)

示例计算:

y <- ddply(x, 'd', transform, v2=(v-min(v))/(max(v)-min(v)))

示例输出:

  d c v  v2
1 1 a 1 0.0
2 1 b 2 0.5
3 1 c 3 1.0
4 2 a 4 0.0
5 2 b 5 0.5
6 2 c 6 1.0

所以我想问问Python高手们:你们会怎么做同样的事情?你有一个数据结构,里面有几个重要的维度。

对于每一个(c)和每一个(d),计算(v-min(v))/(max(v)-min(v)),并把这个结果和对应的(d,c)配对在一起。

你可以随意使用任何数据结构,只要它们在处理合理大的数据集时(那些能放进内存的)速度快就行。

3 个回答

2

如果你使用 numpyscipy,你会发现性能会更好。

虽然代码可能看起来不太好,但运行速度会更快。如果你用 pandas 的方法处理的组数非常多,速度可能会很慢,甚至比 R 还要差。而使用下面的方法总是会比 R 快:

import numpy as np
import numpy.lib.recfunctions
from scipy import ndimage

x = np.rec.fromarrays(([1,1,1,2,2,2],['a','b','c']*2,range(1, 7)), names='d,c,v')

unique, groups = np.unique(x['d'], False, True)
uniques = range(unique.size)
mins = ndimage.minimum(x['v'], groups, uniques)[groups]
maxs = ndimage.maximum(x['v'], groups, uniques)[groups]

x2 = np.lib.recfunctions.append_fields(x, 'v2', (x['v'] - mins)/(maxs - mins + 0.0))

#save as csv
np.savetxt('file.csv', x2, delimiter=';')
5

听起来你想要使用pandas这个工具,以及分组或聚合的功能。

20

确实,pandas 是在Python中处理这个问题的合适工具(我认为也是唯一的工具)。它的功能可能没有plyr那么神奇,但下面是如何使用groupby功能来实现的:

df = DataFrame({'d' : [1.,1.,1.,2.,2.,2.],
                'c' : np.tile(['a','b','c'], 2),
                'v' : np.arange(1., 7.)})
# in IPython
In [34]: df
Out[34]: 
   c  d  v
0  a  1  1
1  b  1  2
2  c  1  3
3  a  2  4
4  b  2  5
5  c  2  6

接下来,写一个简单的变换函数:

def f(group):
    v = group['v']
    group['v2'] = (v - v.min()) / (v.max() - v.min())
    return group

注意,这个函数也能处理缺失值,因为v变量是一个pandas的Series对象。

现在根据d列进行分组,并应用函数f:

In [36]: df.groupby('d').apply(f)
Out[36]: 
   c  d  v  v2 
0  a  1  1  0  
1  b  1  2  0.5
2  c  1  3  1  
3  a  2  4  0  
4  b  2  5  0.5
5  c  2  6  1  

撰写回答