我有巨大的数据框,十万行和一列。
我的数据是这样的:
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
我想使用以下公式计算速度:
我使用了代码:
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
但是此代码需要花费大量时间, 您介意给另一个想法更简单,快速的过程还是使用多处理模块。 谢谢
答案 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^2
,del_Y^2
和del_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
您可以过滤出最后一行(计算列t
,x2
和y2
为空),用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来实现: