[英]For loop pandas and numpy: Performance
我已經編寫了以下 for 循環。 主要思想是,在“A_D”列中每次出現“D”時,它都會查找某些特定條件應該發生的所有可能情況。 當所有條件都得到驗證時,一個值被添加到列表中。
a = []
for i in df.index:
if df['A_D'][i] == 'D':
if df['TROUND_ID'][i] == ' ':
vb = df[(df['O_D'] == df['O_D'][i])
& (df['A_D'] == 'A' )
& (df['Terminal'] == df['Terminal'][i])
& (df['Operator'] == df['Operator'][i])]
number = df['number_ac'][i]
try: ## if all the conditions above are verified a value is added to a list
x = df.START[i] - pd.Timedelta(int(number), unit='m')
value = vb.loc[(vb.START-x).abs().idxmin()].FlightID
except: ## if are not verified, several strings are added to the list
value = 'No_link_found'
else:
value = 'Has_link'
else:
value = 'IsArrival'
a.append(value)
我的主要問題是 df 有數百萬行,因此這個 for 循環太耗時了。 是否有任何不需要使用 for 循環的矢量化解決方案?
最初的一組改進:使用apply
而不是循環; 在df["A_D"] == "A"
的行的開頭創建第二個數據幀; 並向量化值x
。
arr = df[df["A_D"] == "A"]
# if the next line is slow, apply it only to those rows where x is needed
df["x"] = df.START - pd.Timedelta(int(df["number_ac"]), unit='m')
def link_func(row):
if row["A_D"] != "D":
return "IsArrival"
if row["TROUND_ID"] != " ":
return "Has_link"
vb = arr[arr["O_D"] == row["O_D"]
& arr["Terminal"] == row["Terminal"]
& arr["Operator"] == row["Operator"]]
try:
return vb.loc[(vb.START - row["x"]).abs().idxmin()].FlightID
except:
return "No_link_found"
df["a"] = df.apply(link_func, axis=1)
使用apply
顯然更有效,但不會自動矢量化計算。 但是根據df
每一行在arr
找到一個值本質上是耗時的,但它的實現效率如何。 考慮是否可以以某種方式將原始數據幀的兩個部分(其中df["A_D"] == "A"
和df["A_D"] == "D"
)改造成寬格式。
編輯:您可以通過將查詢字符串存儲在df
來加快對arr
的查詢,如下所示:
df["query_string"] = ('O_D == "' + df["O_D"]
+ '" & Terminal == "' + df["Terminal"]
+ '" & Operator == "' + df["Operator"] + '"')
def link_func(row):
vb = arr.query(row["query_string"])
try:
row["a"] = vb.loc[(vb.START - row["x"]).abs().idxmin()].FlightID
except:
row["a"] = "No_link_found"
df.query('(A_D == "D") & (TROUND_ID == " ")').apply(link_func, axis=1)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.