簡體   English   中英

熊貓的論據因行而異

[英]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_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,)的數組。 由於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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM