【发布时间】:2016-05-31 23:36:50
【问题描述】:
我有一个包含很多行的数据框。我正在使用自定义函数生成的数据附加一列,如下所示:
import numpy
df['new_column'] = numpy.vectorize(fx)(df['col_a'], df['col_b'])
# takes 180964.377 ms
它工作正常,我想做的是加快速度。 col_a 和 col_b 的独特组合实际上只有一小部分。许多迭代是多余的。我在想也许pandas 会自己解决这个问题,但我认为情况并非如此。考虑一下:
print len(df.index) #prints 127255
df_unique = df.copy().drop_duplicates(['col_a', 'col_b'])
print len(df_unique.index) #prints 9834
我还通过运行以下命令说服了自己可能的加速:
df_unique['new_column'] = numpy.vectorize(fx)(df_unique['col_a'], df_unique['col_b'])
# takes 14611.357 ms
由于有很多冗余数据,我想做的是更新大数据帧(df127255 行),但只需要运行fx 函数最少次数(9834 次)。这是因为 col_a 和 col_b 的所有重复行。当然这意味着df 中会有多行对col_a 和col_b 具有相同的值,但是没关系,df 的其他列不同并且使每一行都是唯一的。
在我创建一个普通的迭代 for 循环以遍历 df_unique 数据帧并对 df 进行条件更新之前,我想问一下是否有更“pythonic”的简洁方式来进行这种更新。非常感谢。
** 更新 **
我创建了上面提到的简单for循环,如下所示:
df = ...
df_unique = df.copy().drop_duplicates(['col_a', 'col_b'])
df_unique['new_column'] = np.vectorize(fx)(df_unique['col_a'], df_unique['col_b'])
for index, row in df_unique.iterrows():
df.loc[(df['col_a'] == row['col_a']) & (df['col_b'] == row['col_b']),'new_column'] = row['new_column']
# takes 165971.890
因此,使用此 for 循环可能会略微提高性能,但与我预期的差不多。
仅供参考
这是fx 函数。它查询一个mysql数据库。
def fx(d):
exp_date = datetime.strptime(d.col_a, '%m/%d/%Y')
if exp_date.weekday() == 5:
exp_date -= timedelta(days=1)
p = pandas.read_sql("select stat from table where a = '%s' and b_date = '%s';" % (d.col_a,exp_date.strftime('%Y-%m-%d')),engine)
if len(p.index) == 0:
return None
else:
return p.iloc[0].close
【问题讨论】:
-
col_a,col_b中的数据是什么样的?他们已经排序了吗? -
它们都是字符串,虽然 col_b 是日期字符串。相当肯定它们是排序的。他们似乎是。
标签: python pandas optimization dataframe