[英]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.