我有一个包含很多行的数据框。我使用自定义函数生成的数据附加一列,如下所示:
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
由于有很多冗余数据,我想做的是更新大数据帧(df
127255行),但只需要运行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
最佳答案
更新:
如果您可以设法将属于table
表的三列['stat','a','b_date']
读取到tab
DF 然后你可以像这样合并它:
tab = pd.read_sql('select stat,a,b_date from table', engine)
df.merge(tab, left_on=[...], right_on=[...], how='left')
旧答案:
您可以将预先计算的 df_unique
DF 与原始 df
DF 合并/连接:
df['new_column'] = df.merge(df_unique, on=['col_a','col_b'], how='left')['new_column']
关于python - Pandas,根据列值的唯一子集追加列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37527401/