繁体   English   中英

如何在 Python 中加速此任务

[英]How to speed up this task in Python

我有一个大 Pandas 数据框,24'000'000 行 × 6 列加上索引。 我需要读取第 1 列中的一个整数(即 = 1 或 2),然后如果第 1 列 = 1,则强制第 3 列中的值为负,如果 = 2,则强制为正。我在 Jupyter 笔记本中使用以下代码:

for i in range(1000):
    if df.iloc[i,1] == 1:
        df.iloc[i,3] = abs(df.iloc[i,3])*(-1)
    if df.iloc[i,1] == 2:
        df.iloc[i,3] = abs(df.iloc[i,3])

上面的代码只需要 2 分 30 秒来运行 1'000 行。 对于 24M 行,需要 41 天才能完成!

有什么不对的。 该代码在相当高端的 PC 上运行在 Jupyter Notebook/Chrome/Windows 中。

Pandas 数据框是用 pd.read_csv 创建的,然后以这种方式排序和索引:

df.sort_values(by = "My_time_stamp", ascending=True,inplace = True)
df = df.reset_index(drop=True)

数据框的创建和排序只需几秒钟。 我有其他计算要在这个数据帧上执行,所以我显然需要了解我做错了什么。

np.where

a = np.where(df.iloc[:, 1].to_numpy() == 1, -1, 1)
b = np.abs(df.iloc[:, 3].to_numpy())
df.iloc[:, 3] = a * b

矢量化:

df.iloc[:, 3] = df.iloc[:, 3].abs() * (2 * (df.iloc[:, 1] != 1) - 1)

解释:

视为 int,布尔系列df.iloc[:, 1] != 1被转换为 1 和 0。 乘以 2,得到 2 和 0。 减一后,第一列为 1 时为 -1,否则为 1。 最后,它乘以第三列的绝对值,这会强制执行符号。

与 for 循环相比,矢量化通常提供一个或两个数量级的加速。

df.iloc[:,3] = df.iloc[:,3].abs().mul( df.iloc[:,-1].map({2:1,1:-1}) )

另一种方法来做到这一点:

import pandas as pd

以数据集为例:

df = pd.DataFrame({'x1':[1,2,1,2], 'x2':[4,8,1,2]})

创建新列,代码值为 -1 和 +1:

df['nx1'] = df['x1'].replace({1:-1, 2:1})

按列相乘:

df['nx1'] * df['x2']

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM