在Python中为大数据集加速每行循环
我想通过根据其他列值(两列或三列以上)将值分配给新列来处理一个大数据集。我有下面的Python代码 我的数据集包含1700万条数据记录。运行脚本需要40多个小时。我是Python新手,在大数据方面经验很少 有人能帮我加快脚本运行时间吗 以下是数据集的示例:在Python中为大数据集加速每行循环,python,pandas,performance,loops,bigdata,Python,Pandas,Performance,Loops,Bigdata,我想通过根据其他列值(两列或三列以上)将值分配给新列来处理一个大数据集。我有下面的Python代码 我的数据集包含1700万条数据记录。运行脚本需要40多个小时。我是Python新手,在大数据方面经验很少 有人能帮我加快脚本运行时间吗 以下是数据集的示例: PId hZ tId tPurp ps oZ dZ oT dT 0 1 50 1040 32 762 748 10.5 12.5 0 1 50 1040 16 748 81 1
PId hZ tId tPurp ps oZ dZ oT dT
0 1 50 1040 32 762 748 10.5 12.5
0 1 50 1040 16 748 81 12.5 12.5
0 1 50 1040 2048 81 1 12.5 12.5
0 1 50 1040 1040 1 762 9.5 9.5
1 1 10 320 320 1 35 17.5 17.5
1 1 10 320 2048 35 1 19.5 19.5
2 1 50 1152 1152 297 102 11.5 12
2 1 50 1152 2048 102 1 12 12
2 1 50 1152 32 1 297 11.5 11.5
3 1 1 2 64 737 184 14 18
3 1 1 2 128 184 713 14 14
3 1 1 2 2048 184 1 18 18
3 1 1 2 2 1 737 9 9
4 1 1 2 2 1 856 9 9
4 1 1 2 2048 296 1 18 18
4 1 1 2 16 856 296 17 18
8 1 50 1056 16 97 7 15 15.5
8 1 50 1056 32 7 816 15.5 1
8 1 50 1056 2048 816 1 1 1
8 1 50 1056 1056 1 97 12 12
下面是Python代码
import pandas as pd
import numpy as np
df_test = pd.read_csv("C:/users/test.csv")
df_test.sort_values(by=['PId','tId','oT','dT'],inplace=True)
ls2t = df_test.groupby(['PId','tId']).nth(-2)
ls2t.reset_index(level=(0,1),inplace=True)
ls2tps=ls2t[['PId','tId','ps']]
ls2tps=ls2tps.rename(columns = {'ps':'ls2ps'})
df_lst = pd.merge(df_test,
ls2tps,
on=['PId','tId'],
how='left')
for index,row in df_lst.iterrows():
if df_lst.loc[index,'oZ']==df_lst.loc[index,'hZ'] and df_lst.loc[index,'ps']==2:
df_lst.loc[index,'d'] = 'A'
elif df_lst.loc[index,'oZ']==df_lst.loc[index,'hZ'] and df_lst.loc[index,'ps']!=2:
df_lst.loc[index,'d']='B'
elif df_lst.loc[index,'ps']==2048 and (df_lst.loc[index,'ls2ps']==2 or df_lst.loc[index,'ls2ps']==514):
df_lst.loc[index,'d']='A'
elif df_lst.loc[index,'ps']==2048 and (df_lst.loc[index,'ls2ps']!=2 and df_lst.loc[index,'ls2ps']!=514):
df_lst.loc[index,'d']='B'
else:
df_lst.loc[index,'d']='C'
od_aggpurp = df_lst.groupby(['oZ','dZ','d']).size().reset_index(name='counts')
od_aggpurp.to_csv('C:/users/test_result.csv')
您应该尝试以下方法,而不是该循环:
df_lst.loc[(df_lst['oZ'] == df_lst['hZ']) & (df_lst['ps'] == 2), 'd'] = 'A'
df_lst.loc[(df_lst['oZ'] == df_lst['hZ']) & (df_lst['ps'] != 2), 'd'] = 'B'
df_lst.loc[(df_lst['ps'] == 2048) & ((df_lst['ls2ps'] == 2) | (df_lst['ls2ps'] == 514)), 'd'] = 'A'
df_lst.loc[(df_lst['ps'] == 2048) & ((df_lst['ls2ps'] != 2) & (df_lst['ls2ps'] != 514)), 'd'] = 'B'
df_lst.loc[(df_lst['d'] != 'A') & (df_lst['d'] != 'B'), 'd'] = 'C'
在这里,您仅从df_lst(使用.loc)中选择具有请求参数的行,但只修改d列
请注意,在数据帧和is&,或is |和not is~
如果您愿意,这应该表现得更好:
oZ_hZ = df_lst['oZ'] == df_lst['hZ']
ps_2 = df_lst['ps'] == 2
df_lst.loc[(oZ_hZ) & (ps_2), 'd'] = 'A'
df_lst.loc[(oZ_hZ) & (~ps_2), 'd'] = 'B'
ps_2048 = df_lst['ps'] == 2048
ls2ps_2 = df_lst['ls2ps'] == 2
ls2ps_514 = df_lst['ls2ps'] == 514
df_lst.loc[(ps_2048) & ((ls2ps_2) | (ls2ps_514)), 'd'] = 'A'
df_lst.loc[(ps_2048) & ((~ls2ps_2) & (~ls2ps_514)), 'd'] = 'B'
df_lst.loc[(df_lst['d'] != 'A') & (df_lst['d'] != 'B'), 'd'] = 'C'
可以还有一个问题与此类似..我认为有两种方法可以解决此问题..首先将数据帧分解为多个块,然后异步执行它们上的逻辑(asyncio会很有帮助)…或者尝试hadoop群集之类的方法..只是一个建议..参数非常感谢您的帮助。我尝试了建议的代码。但它给了我一个错误:级数的真值是模糊的。使用a.empty、a.bool()、a.item()、a.any()或a.all()。对于代码。我猜这可能是因为df_lst.loc[df_lst['oZ']==df_lst['hZ']&df_lst['ps']==2]['d']生成了一个序列,所以不能给它赋值。所以我使用了df_lst.loc[df_lst['oZ']==df_lst['hZ']&df_lst['ps']==2,'d']='A'。还是一样的错误。我想不出是怎么回事。很抱歉我忘了更多的论文。现在应该可以了。是的,df_lst['d]==2048生成一个布尔序列,但在本例中,它仅用于从数据帧中选择元素。非常感谢您的帮助。真的很有帮助!!!它只需要不到2分钟就可以运行!!!但是我对df_lst.loc[(oZ_hZ)和(ps_2)]['d']='a'做了一个小的修改。因为它没有为d列赋值。所以我把代码改为df_lst.loc[((oZ_-hZ)和(ps_-2)),'d']='A'。我不确定这两种代码的区别。但后一种方法有效。我真的很高兴它有帮助!你是对的!正如他们在这里所说,第一个版本有时有效,有时无效,因为它可能会在其他地方创建副本。