Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 熊猫适用于不同行的参数_Python_Pandas - Fatal编程技术网

Python 熊猫适用于不同行的参数

Python 熊猫适用于不同行的参数,python,pandas,Python,Pandas,我有一个包含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

我有一个包含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
如果大小为整数,则可以正常工作:

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函数呢?

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

然后更改
ravel
功能:

def rare(x):
    size = x['size']
    y = x.values[:-1]
    ...
或者,如果您不想更改
ravel
,请将其包装:

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

您可以将结果表示为对整个NumPy数组的计算,而不是对
varspec
的每一行调用
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],))
这表明
使用_rare
使用_array
产生相同的结果:

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



这利用了
scipy.misc.comb
可以接受NumPy数组作为输入这一事实。因此,您可以调用
comb(diff,size)
其中
diff
是一个形状数组(225,50),而
size
是一个形状数组(50,)。由于
size
仅用于调用
comb
,因此只需两次调用
comb
,即可执行所有计算。不需要每行循环。

comb
scipy.misc.comb
函数吗?为什么不在数据中创建
size
另一列,以便将其作为
apply
的一部分传递?这实际上是我目前修补的解决方案。我想知道是否还有更优雅的东西。我自己也曾试图想出这样的东西,但被卡住了。谢谢
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