Pandas适用的论点因人而异

2024-05-29 02:04:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含50行的数据帧,例如来自R的BCI数据

import pandas.rpy.common as com
varespec = com.load_data('BCI', 'vegan')

我试图将一个函数应用于每一行,其中该函数接受一个“size”参数。你知道吗

def rare(y, size):
    notabs = ~np.isnan(y)
    t = y[notabs]
    N = np.sum(t)
    diff = N - t
    rare = np.sum(1 - comb(diff, size)/comb(N, size))
    return rare

如果size是整数,则可以正常工作:

varespec.apply(rare, axis=1, args=(20,))

我想做的是让size成为一个由50个元素组成的数组,所有元素都不同,这样每一行都有一个惟一的size值。如果我把大小设为50,它会传递整个向量,函数就不起作用了。我该怎么做

varespec.apply(rare, axis=1, args=(size,))

是否为每行使用大小唯一的元素?我可以做循环:

for i in xrange(50):
    rare(varespec.iloc[i,:], size[i])

但是有没有更好的方法来使用apply函数呢?你知道吗


Tags: 数据函数com元素sizenpdiffapply
2条回答

可以将该向量作为列添加到数据帧中(如果需要,请稍后删除):

varespec['size'] = size

然后更改rare函数:

def rare(x):
    size = x['size']
    y = x.values[:-1]
    ...

或者,如果不想更改rare,请将其包装:

def rare_wrapper(x):
    size = x['size']
    y = x.values[:-1]
    return rare(y, size)

您可以将结果表示为对整个NumPy数组的计算,而不是对varespec的每一行调用一次rare

import pandas as pd
import pandas.rpy.common as com
import scipy.misc as misc
import numpy as np
np.random.seed(1)

def rare(y, size):
    notabs = ~np.isnan(y)
    t = y[notabs]
    N = np.sum(t)
    diff = N - t
    rare = np.sum(1 - misc.comb(diff, size)/misc.comb(N, size))
    return rare

def using_rare(size):
    return np.array([rare(varespec.iloc[i,:], size[i]) for i in xrange(50)])

def using_arrays(size):    
    N = varespec.sum(axis='columns', skina=True)
    diff = (N[:, np.newaxis] - varespec.values).T
    return np.sum(1 - misc.comb(diff, size) / misc.comb(N, size), axis=0)

varespec = com.load_data('BCI', 'vegan')
size = np.random.randint(varespec.shape[1], size=(varespec.shape[0],))

这表明using_rareusing_arrays产生相同的结果:

expected = using_rare(size)
result = using_arrays(size)
assert np.allclose(result, expected)

In [229]: %timeit using_rare(size)
10 loops, best of 3: 36.2 ms per loop

In [230]: %timeit using_arrays(size)
100 loops, best of 3: 2.89 ms per loop

这利用了scipy.misc.comb可以接受NumPy数组作为输入这一事实。所以可以调用comb(diff, size),其中diff是一个形状数组(225,50),而size是一个形状数组(50,50)。因为size只在对comb的调用中使用,所以只需两次对comb的调用就可以执行所有的计算。不需要每行循环。你知道吗

相关问题 更多 >

    热门问题