python - for循环pandas和numpy : Performance

标签 python pandas performance loops numpy

我编写了以下 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)

使用applyapparently more efficient但不会自动矢量化计算。但是,无论实现的效率如何,根据 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)

关于python - for循环pandas和numpy : Performance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52225908/

相关文章:

python - 按索引选择 MultiIndex 数据框中的行而不丢失任何级别

objective-c - Objective-C 中点符号与方法调用之间的性能差异

Azure Blob 存储流性能问题

java - 规范化可迭代类型,使得输出是总和为 1 的可迭代 float

python - 类型错误 : unsupported operand type(s) for +: 'int' and 'str' error when pulling data from API with discord. py

python - 找出所有的方法来决定 list 分为三

python - 在 pandas.DataFrame 的对角线上设置值

python - 根据针对正则表达式 Pandas 检查的现有列填充新列

java - 为什么 (a*b != 0) 在 Java 中比 (a != 0 && b != 0) 快?

python - 使用 Python 获取 Azure DevOps 项目工作项时进行身份验证