在一组(可能很长(合并操作上,我需要一个tqdm
进度条。在我的应用程序中,我有一组级联操作,如下面的
data = data.merge(get_data_source1(), on="id", how="left")
.merge(get_data_source2(), on="id", how="left")
...
.merge(get_data_sourceN(), on="id", how="left")
get_data_source<i>
函数做什么并不相关,它们从某个地方(例如,从不同的文件或不同的DB(提取数据,并且它们返回带有"0"的DataFrame;id";列,这需要几秒钟的时间。
我需要一个带有N的进度条。这可能是可行的,将每个合并操作封装在lambda
函数中,并将它们放入可迭代的函数中,但如果我尝试思考它,它看起来像是一个过度设计和难以阅读的解决方案(如果你认为我错了,请纠正我(。此外,我知道可以使用progress_apply
函数(如本文所述(为每个合并操作添加一个进度条,但这将生成多个(N(短进度条,而不是一个。
为了模拟工作设置,让我们考虑一下这个玩具示例
import pandas as pd
import numpy as np
import time
data = pd.DataFrame(np.random.randint(0,100,size=(100,3)), columns=["id","A", "B"])
def get_data(col):
time.sleep(1.0)
return pd.DataFrame(np.random.randint(0,100,size=(100,2)), columns=["id",col])
data.merge(get_data("C"), on="id", how="left")
.merge(get_data("D"), on="id", how="left")
.merge(get_data("E"), on="id", how="left")
.merge(get_data("F"), on="id", how="left")
.merge(get_data("G"), on="id", how="left")
.merge(get_data("H"), on="id", how="left")
解决这个问题的最佳方法是什么?
我建议使用functools.reduce.
这里有一个关于一些示例数据帧的片段,但它可以用于任何可迭代的数据帧,只需使用tqdm
即可。
import functools
import numpy as np
import pandas as pd
from tqdm.auto import tqdm
N = 10
columns = [["A", "B"], ["C"], ["D", "E", "F"]]
dfs = [
pd.DataFrame(
{
"key": range(N),
**{c: np.random.rand(N) for c in cols}
}
)
for cols in columns
]
functools.reduce(lambda x, y: x.merge(y), tqdm(dfs[1:]), dfs[0])
您可以使用要应用函数get_data的值创建一个列表,并使用tqdm迭代该列表。
import pandas as pd
import numpy as np
import time
import tqdm
data = pd.DataFrame(np.random.randint(0,100,size=(100,3)), columns=["id","A", "B"])
def get_data(col):
time.sleep(1.0)
return pd.DataFrame(np.random.randint(0,100,size=(100,2)), columns=["id",col])
values = ["C","D","E","F","G","H"]
for i in tqdm.tqdm(values):
data = data.merge(get_data(i), on="id", how="left")
data
您可以像上面的例子一样,在每个步骤将合并的数据帧分配给数据数据帧,也可以使用inplace参数来避免在每个步骤返回新的数据帧。
编辑:由于所有的get_data函数都是不同的,我建议像问题一样,用这些函数创建一个可迭代的函数。不需要使用lambdas,如下例所示:
functions = [get_data1,get_data2,get_data3]
for func in functions:
data = func(param1,param2,param3)
这将迭代列表中的所有函数,并使用给定的参数执行它们。