![](/img/trans.png)
[英]Apply function to pandas Series with argument (which varies for every element)
[英]Pandas apply with argument that varies by row
我有一個包含50行的數據框,例如R中的BCI數據。
import pandas.rpy.common as com
varespec = com.load_data('BCI', 'vegan')
我正在嘗試將函數應用於每一行,其中函數采用“大小”參數。
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值。 如果我將size設為50的向量,它將傳遞整個向量,並且該功能將不起作用。 我該怎么做
varespec.apply(rare, axis=1, args=(size,))
每行使用大小的唯一元素? 我可以做循環:
for i in xrange(50):
rare(varespec.iloc[i,:], size[i])
但是使用應用功能還有更好的方法嗎?
您可以將結果表示為對整個NumPy數組的計算,而不是通過對varespec
每一行調用一次rare
來完成varespec
:
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_rare
和using_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,)的數組。 由於size
在電話僅用於comb
,就可以只用兩個電話來進行所有的計算comb
。 每行無需循環。
您可以將該向量作為一列添加到數據框中(如果需要,請稍后刪除):
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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.