[英]Python Pandas: Why is numpy so much faster than Pandas for column assignment? Can I optimize further?
我正在通过将分类变量转换为二进制矩阵来预处理机器学习分类任务的数据,主要使用pd.get_dummies()
。 这适用于单个Pandas DataFrame列,并输出一个新的DataFrame,其行数与原始列中唯一数量的分类变量的原始和宽度相同。
我需要为形状的数据框架完成此操作: (3,000,000 x 16)
,它输出一个形状为二进制矩阵: (3,000,000 x 600)
。
在此过程中,转换为二进制矩阵pd.get_dummies()
的步骤非常快,但使用pd.DataFrame.loc[]
对输出矩阵的分配要慢得多。 因为我有开关直接保存到np.ndarray
是要快得多,我只是想知道为什么? ( 请参阅问题底部的终端输出进行时间比较 )
nb正如评论中所指出的,我可以在整个帧上使用所有pd.get_dummies()
。 但是,有些列需要定制的预处理,即:放入存储桶。 要处理的最困难的列是一个包含一串标签的列(或者,
或者,
必须像这样处理: df[col].str.replace(' ','').str.get_dummies(sep=',')
。此外,预处理的训练集和测试集需要相同的列集(继承自all_cols),因为一旦它们被分解成矩阵,它们可能不具有相同的特征。
请参阅以下代码了解每个版本
DataFrame版本:
def preprocess_df(df):
with open(PICKLE_PATH + 'cols.pkl', 'rb') as handle:
cols = pickle.load(handle)
x = np.zeros(shape=(len(df),len(cols)))
# x = pd.DataFrame(columns=all_cols)
for col in df.columns:
# 1. make binary matrix
df_col = pd.get_dummies(df[col], prefix=str(col))
print "Processed: ", col, datetime.datetime.now()
# 2. assign each value in binary matrix to col in output
for dummy_col in df_col.columns:
x.loc[:, dummy_col] = df_col[dummy_col]
print "Assigned: ", col, datetime.datetime.now()
return x.values
np版本:
def preprocess_np(df):
with open(PICKLE_PATH + 'cols.pkl', 'rb') as handle:
cols = pickle.load(handle)
x = np.zeros(shape=(len(df),len(cols)))
for col in df.columns:
# 1. make binary matrix
df_col = pd.get_dummies(df[col], prefix=str(col))
print "Processed: ", col, datetime.datetime.now()
# 2. assign each value in binary matrix to col in output
for dummy_col in df_col.columns:
idx = [i for i,j in enumerate(all_cols) if j == dummy_col][0]
x[:, idx] = df_col[dummy_col].values.T
print "Assigned: ", col, datetime.datetime.now()
return x
定时输出( 10,000
示例)
DataFrame版本:
Processed: Weekday
Assigned: Weekday 0.437081
Processed: Hour 0.002366
Assigned: Hour 1.33815
np版本:
Processed: Weekday
Assigned: Weekday 0.006992
Processed: Hour 0.002632
Assigned: Hour 0.008989
有没有不同的方法来进一步优化这个? 我感兴趣的是,目前我正在放弃一个可能有用的功能,因为它太慢,无法处理额外的15,000
列到输出。
关于我正在采取的方法的任何一般建议也表示赞赏!
谢谢
一个实验是切换到x.loc[:, dummy_col] = df_col[dummy_col].values
。 如果输入是一个系列,pandas正在检查每个赋值的索引顺序。 如果没有必要,使用ndarray进行分配会将其关闭,这样可以提高性能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.