在一系列合并操作上使用 tqdm
Use tqdm over a sequence of merge operations
我需要一组(可能很长)合并操作的 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>
函数的作用无关紧要,它们从某个地方(例如,从不同的文件或不同的数据库)提取数据,并且它们 returns 一个带有“id”的 DataFrame列,这需要几秒钟。
我需要一个与 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")
解决问题的最佳方法是什么?
您可以使用要应用函数 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 函数都不同,我建议像问题一样创建一个可迭代的函数。不需要使用 lambda,如下例所示:
functions = [get_data1,get_data2,get_data3]
for func in functions:
data = func(param1,param2,param3)
这将遍历列表的所有函数并使用给定的参数执行它们。
我建议使用 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])
我需要一组(可能很长)合并操作的 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>
函数的作用无关紧要,它们从某个地方(例如,从不同的文件或不同的数据库)提取数据,并且它们 returns 一个带有“id”的 DataFrame列,这需要几秒钟。
我需要一个与 N 一起使用的进度条。将每个合并操作封装在 lambda
函数中并将它们放入一个可迭代对象中可能是可行的,但它看起来像是一个过度设计且难以阅读的解决方案,如果我试着想想(如果你认为我错了请纠正我)。
另外,我知道可以使用 progress_apply
函数(如报告的
为了模拟工作设置,让我们考虑这个玩具示例
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")
解决问题的最佳方法是什么?
您可以使用要应用函数 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 函数都不同,我建议像问题一样创建一个可迭代的函数。不需要使用 lambda,如下例所示:
functions = [get_data1,get_data2,get_data3]
for func in functions:
data = func(param1,param2,param3)
这将遍历列表的所有函数并使用给定的参数执行它们。
我建议使用 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])