(速度计算)如何简化方法?

时间:2018-06-23 03:15:46

标签: python pandas loops dataframe multiprocessing

我有巨大的数据框,十万行和一列。

我的数据是这样的:

df

MAC T_1 X_1 Y_1 T_2 X_2 Y_2 T_3 X_3 Y_3 T_4 X_4 Y_4 T_5 X_5 Y_5 T_6 X_6 Y_6 T_7 X_7 Y_7
ID1 1   1   1   1   1   1   2   1   2   3   1   3   3   1   3   4   1   4   5   1   5
ID2 6   2   5   6   2   5   7   3   5   7   3   5   8   4   5   9   5   5   10  5   4
ID3 1   1   1   2   1   2   3   1   3   3   1   3   4   1   4   5   1   5   6   2   5   

我想使用以下公式计算速度:

enter image description here

我使用了代码:

df = pd.read_csv("data.csv")
def v_2(i):
     return (df.ix[x,(5+3*(i-1))]-df.ix[x,(2+3*(i-1))])**2 + (df.ix[x,(6+3*(i-1))]-df.ix[x,(3+3*(i-1))])**2

def v(i):
    if (df.ix[x,(4+3*(i-1))]-df.ix[x,(1+3*(i-1))]) ==0:
        return 0
    else:
        if (df.ix[x,(4+3*(i-1))]-df.ix[x,(1+3*(i-1))]) <0:
            return 0
        else:
            return math.sqrt(v_2(i)) / (df.ix[x,(4+3*(i-1))]-df.ix[x,(1+3*(i-1))]) 

for i in range(1,int((len(df.columns)-1)/3)):
v_result = list()
for x in range(len(df.index)):
    v_2(i)
    v(i)
    v_result.append(v(i))
df_result[i]=v_result

我的预期结果:

MAC V1  V2  V3  V4  V5  V6
ID1 0   1   1   0   1   1
ID2 0   1   0   1   1   1
ID3 1   1   0   1   1   1

但是此代码需要花费大量时间, 您介意给另一个想法更简单,快速的过程还是使用多处理模块。 谢谢

2 个答案:

答案 0 :(得分:1)

可以通过首先重塑数据来大大加快计算速度,从而可以使用有效的熊猫方法。如果那还不够快,则可以转到numpy数组并在那里应用函数。

首先将数据从 wide 格式整形为 long 格式,以便只有3列T, X, Y。列后缀_1_2等被拆分为新索引。

df = df.set_index('MAC')
df.columns = pd.MultiIndex.from_arrays(zip(*df.columns.str.split('_')))
df = df.stack()

这将产生以下数据帧:

        T  X  Y
MAC
ID1 1   1  1  1
    2   1  1  1
    3   2  1  2
    4   3  1  3
    5   3  1  3
    6   4  1  4
    7   5  1  5
ID2 1   6  2  5
    2   6  2  5
    3   7  3  5
    4   7  3  5
    5   8  4  5
    6   9  5  5
    7  10  5  4
ID3 1   1  1  1
    2   2  1  2
    3   3  1  3
    4   3  1  3
    5   4  1  4
    6   5  1  5
    7   6  2  5

接下来计算del_X^2del_Y^2del_t我希望前缀del的用法是明确的)。使用这两个实用程序函数可以避免重复,这很容易做到。

def f(x):
    return x.shift(-1) - x

def f2(x):
    return f(x)**2

更新:功能说明

  

第一个函数为所有F(W,n) = W(n+1) - W(n)计算n,其中n是数组W的索引。第二个函数对参数进行平方。这些函数用于计算距离的平方。有关更多信息和示例,请参见pd.Series.shift的文档。

使用小写的列名作为上面的del前缀和后缀2的平方:

df['x2'] = df.groupby(level=0).X.transform(f2)
df['y2'] = df.groupby(level=0).Y.transform(f2)
df['t'] = df.groupby(level=0).Y.transform(f)
df['v'] = np.sqrt(df.x2 + df.y2) / df.t

df.v.unstack(0)

产生以下内容,与您的输出类似,但转置。

MAC  ID1  ID2  ID3
1    NaN  NaN  1.0
2    1.0  1.0  1.0
3    1.0  NaN  NaN
4    NaN  1.0  1.0
5    1.0  1.0  1.0
6    1.0  1.0  1.0
7    NaN  NaN  NaN

您可以过滤出最后一行(计算列tx2y2为空),用0填充v中的np.nan,转置,重命名列并重置索引以获得所需的结果。

result = df[pd.notnull(df.t)].v.unstack(0).fillna(0).T
result.columns = ['V'+x for x in result.columns]
result.reset_index()
# outputs:

   MAC   V1   V2   V3   V4   V5   V6
0  ID1  0.0  1.0  1.0  0.0  1.0  1.0
1  ID2  0.0  1.0  0.0  1.0  1.0  1.0
2  ID3  1.0  1.0  0.0  1.0  1.0  1.0

答案 1 :(得分:0)

如果您想要真正的速度,建议您使用Apache Spark。 您可以按照本文档中的说明通过将函数传递给Spark来实现:

Passing function to Spark