我正在手动将熊猫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
问题出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] 删除。
我来说两句