将df的子集传递给函数-Python

强子

我正在手动将熊猫df中的特定值传递给函数。很好,但是我希望使过程更高效。具体来说,我首先对中的所有连续值进行子集化Item然后,我将各自的值输入Val并将其传递给func这产生了我需要的值。对于较小的df来说可以,但是对于较大的数据集来说效率不高。

我只是希望使此过程更有效,以将值应用于原始df。

import pandas as pd
import numpy as np

df = pd.DataFrame({ 
            'Time' : ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15'],                   
            'Val' : [35,38,31,30,35,31,32,34,36,38,39,30,25,26,27],                   
            'Item' : ['X','X','X','X','X','Y','Y','Y','Y','Y','Y','X','X','X','X'],  
                    })

df1 = df.groupby([df['Item'].ne(df['Item'].shift()).cumsum(), 'Item']).size()

X1 = df[0:5]
Y1 = df[5:11]
X2 = df[11:15]

V1 = X1['Val1'].reset_index(drop = True)
V2 = Y1['Val1'].reset_index(drop = True)
V3 = X2['Val1'].reset_index(drop = True)

def func(U, m = 2, r = 0.2):

        def _maxdist(x_i, x_j):
            return max([abs(ua - va) for ua, va in zip(x_i, x_j)])

        def _phi(m):
            x = [[U[j] for j in range(i, i + m - 1 + 1)] for i in range(N - m + 1)]
            C = [len([1 for x_j in x if _maxdist(x_i, x_j) <= r]) / (N - m + 1.0) for x_i in x]
            return (N - m + 1.0)**(-1) * sum(np.log(C))

        N = len(U)

        return abs(_phi(m + 1) - _phi(m))

print(func(V1))
print(func(V2))
print(func(V3))

出:

0.287682072452
0.223143551314
0.405465108108

如果我只是尝试使用groupby来应用该函数,则返回KeyError: 0除非我重置索引,否则该功能将不起作用。

df1 = df.groupby(['Item']).apply(func)

KeyError:0

预期输出:

   Time  Val1 Item   func
0     1    35    X  0.287
1     2    38    X  0.287
2     3    31    X  0.287
3     4    30    X  0.287
4     5    35    X  0.287
5     6    31    Y  0.223
6     7    32    Y  0.223
7     8    34    Y  0.223
8     9    36    Y  0.223
9    10    38    Y  0.223
10   11    39    Y  0.223
11   12    30    X  0.405
12   13    25    X  0.405
13   14    26    X  0.405
14   15    27    X  0.405
安迪(Andy L.)

问题出U[j]_phi功能上。j是位置索引,因此您可以使用U.iloc[j]或将其更改为列表,然后直接从列表开始工作。似乎在列表上工作比使用更快iloc我的修复程序将其更改为列表并在列表上工作。该生产线x = ..._phi也可以使用一些修改,使之更短。

方法1

def func(U, m = 2, r = 0.2):

    def _maxdist(x_i, x_j):
        return max([abs(ua - va) for ua, va in zip(x_i, x_j)])

    def _phi(m):
        x = [U.tolist()[i:i + m] for i in range(N - m + 1)] #change at this line
        C = [len([1 for x_j in x if _maxdist(x_i, x_j) <= r]) / (N - m + 1.0) for x_i in x]
        return (N - m + 1.0)**(-1) * sum(np.log(C))

    N = len(U)

    return abs(_phi(m + 1) - _phi(m))

s像您一样创建自定义groupID ,然后按groupby进行s调用transform

s = df['Item'].ne(df['Item'].shift()).cumsum()
df['func'] = df.groupby(s).Val.transform(func)

Out[1090]:
   Time  Val Item      func
0     1   35    X  0.287682
1     2   38    X  0.287682
2     3   31    X  0.287682
3     4   30    X  0.287682
4     5   35    X  0.287682
5     6   31    Y  0.223144
6     7   32    Y  0.223144
7     8   34    Y  0.223144
8     9   36    Y  0.223144
9    10   38    Y  0.223144
10   11   39    Y  0.223144
11   12   30    X  0.405465
12   13   25    X  0.405465
13   14   26    X  0.405465
14   15   27    X  0.405465

方法2:较短,但可读性较差。as_strided使用numpy.lib.stride_tricks

def func(U, m = 2, r = 0.2):

    def _phi(m):
        strd = U.to_numpy().strides[0]
        x = as_strided(U.to_numpy(), (N-m+1, m), (strd, strd))
        C = (np.abs(x - x[:,None]).max(-1) <= r).sum(-1) / (N - m + 1.0)    
        return np.sum(np.log(C)) / (N - m + 1.0)

    N = len(U)

    return abs(_phi(m + 1) - _phi(m))      

您需要导入as_strided并创建groupID并调用groupby transform作为方法1

from numpy.lib.stride_tricks import as_strided

s = df['Item'].ne(df['Item'].shift()).cumsum()
df['func'] = df.groupby(s).Val.transform(func)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章