使用 DataFrame 时迭代一对行
Iterating with a pair of rows when working with DataFrame
为了遍历 DataFrame 的每一行,我使用 .iterrows()
:
list_soccer = pd.DataFrame({
'EventName': [obj_event.event.name for obj_event in matches],
'IDEvent': [obj_event.event.id for obj_event in matches],
'LocalEvent': [obj_event.event.venue for obj_event in matches],
'CodeCountry': [obj_event.event.country_code for obj_event in matches],
'TimeZone': [obj_event.event.time_zone for obj_event in matches],
'OpenDate': [obj_event.event.open_date for obj_event in matches],
'Total_Market': [obj_event.market_count for obj_event in matches],
'Local_Date': [obj_evento.event.open_date.replace(tzinfo=datetime.timezone.utc).astimezone(tz=None)
for obj_evento in matches]
})
for_iterate = list_soccer.reset_index()
for_iterate = for_iterate[for_iterate['EventName'].str.contains(" v ")]
data_for_compare = (datetime.datetime.utcnow()).strftime("%Y-%m-%d %H:%M")
for_iterate = for_iterate[for_iterate['OpenDate'] >= data_for_compare]
for index, example_dataframe in for_iterate.iterrows():
multiprocessing.Process(target=add_hour, args=(example_dataframe,))
因为我需要将这次迭代的速度加倍(同时调用两个 multiprocessing
),所以我正在寻找一种同时使用两条线的方法。
如果它是一个常规列表(请注意我在下面给出这个例子只是为了演示我需要什么,我知道列表和数据框之间没有任何相似之处),我可以这样做:
a_list = ['a','b','c','d']
a_pairs = [a_list[i:i+2] for i in range(0, len(a_list)-1, 2)]
# a_pairs = [['a','b'],['c','d']]
for a, b in a_pairs:
multiprocessing.Process(target=add_hour, args=(a,))
multiprocessing.Process(target=add_hour, args=(b,))
我应该如何使用 DataFrame 同时处理两行?
在这个问题中,我找到了两个答案,但它们提供了在 DataFrame 中重复值的选项:
我无法创建的是一个模型,这样行就不会重复,例如,使用行 0 and 1
然后使用 2 and 3
然后使用 4 and 5
,所以也许有人说这个问题重复了,但实际上我的需求不同,我无法根据需要将这些选项转换为一个选项。
您应该能够将 DataFrame 一分为二,使用与列表类似的索引。
然后,您可以一次遍历两者,这会按顺序一次给您两行(所以 0,1 然后 2,3 等)
df_a = for_iterate.iloc[::2] # Get all the even rows
df_b = for_iterate.iloc[1::2] # Get all the odd rows
for (_, example_dataframe_a), (_, example_dataframe_b) in zip(df_a.iterrows(), df_b.iterrows()):
multiprocessing.Process(target=add_hour, args=(example_dataframe_a,))
multiprocessing.Process(target=add_hour, args=(example_dataframe_b,))
(虽然我不清楚为什么你需要为数据帧的每一行生成一个进程,而不是两个进程,每个 for_iterate
的一半)。
或者:
您可以尝试使用 multiprocessing.Pool.map()
一次执行两个请求。与上面的方法不同,一个新的请求会在前一个请求完成后立即发出(因此它不会等待两个都完成后再分派下两个),并且只需要两个进程可能是 re-used:
from multiprocessing import Pool
def add_hour_wrapper(data):
# iterrows returns two arguments, we only want one
_, row = data
return add_hour(row)
pool = Pool(2) # 2 processes
pool.map(add_hour, for_iterate.iterrows())
为了遍历 DataFrame 的每一行,我使用 .iterrows()
:
list_soccer = pd.DataFrame({
'EventName': [obj_event.event.name for obj_event in matches],
'IDEvent': [obj_event.event.id for obj_event in matches],
'LocalEvent': [obj_event.event.venue for obj_event in matches],
'CodeCountry': [obj_event.event.country_code for obj_event in matches],
'TimeZone': [obj_event.event.time_zone for obj_event in matches],
'OpenDate': [obj_event.event.open_date for obj_event in matches],
'Total_Market': [obj_event.market_count for obj_event in matches],
'Local_Date': [obj_evento.event.open_date.replace(tzinfo=datetime.timezone.utc).astimezone(tz=None)
for obj_evento in matches]
})
for_iterate = list_soccer.reset_index()
for_iterate = for_iterate[for_iterate['EventName'].str.contains(" v ")]
data_for_compare = (datetime.datetime.utcnow()).strftime("%Y-%m-%d %H:%M")
for_iterate = for_iterate[for_iterate['OpenDate'] >= data_for_compare]
for index, example_dataframe in for_iterate.iterrows():
multiprocessing.Process(target=add_hour, args=(example_dataframe,))
因为我需要将这次迭代的速度加倍(同时调用两个 multiprocessing
),所以我正在寻找一种同时使用两条线的方法。
如果它是一个常规列表(请注意我在下面给出这个例子只是为了演示我需要什么,我知道列表和数据框之间没有任何相似之处),我可以这样做:
a_list = ['a','b','c','d']
a_pairs = [a_list[i:i+2] for i in range(0, len(a_list)-1, 2)]
# a_pairs = [['a','b'],['c','d']]
for a, b in a_pairs:
multiprocessing.Process(target=add_hour, args=(a,))
multiprocessing.Process(target=add_hour, args=(b,))
我应该如何使用 DataFrame 同时处理两行?
在这个问题中,我找到了两个答案,但它们提供了在 DataFrame 中重复值的选项:
我无法创建的是一个模型,这样行就不会重复,例如,使用行 0 and 1
然后使用 2 and 3
然后使用 4 and 5
,所以也许有人说这个问题重复了,但实际上我的需求不同,我无法根据需要将这些选项转换为一个选项。
您应该能够将 DataFrame 一分为二,使用与列表类似的索引。
然后,您可以一次遍历两者,这会按顺序一次给您两行(所以 0,1 然后 2,3 等)
df_a = for_iterate.iloc[::2] # Get all the even rows
df_b = for_iterate.iloc[1::2] # Get all the odd rows
for (_, example_dataframe_a), (_, example_dataframe_b) in zip(df_a.iterrows(), df_b.iterrows()):
multiprocessing.Process(target=add_hour, args=(example_dataframe_a,))
multiprocessing.Process(target=add_hour, args=(example_dataframe_b,))
(虽然我不清楚为什么你需要为数据帧的每一行生成一个进程,而不是两个进程,每个 for_iterate
的一半)。
或者:
您可以尝试使用 multiprocessing.Pool.map()
一次执行两个请求。与上面的方法不同,一个新的请求会在前一个请求完成后立即发出(因此它不会等待两个都完成后再分派下两个),并且只需要两个进程可能是 re-used:
from multiprocessing import Pool
def add_hour_wrapper(data):
# iterrows returns two arguments, we only want one
_, row = data
return add_hour(row)
pool = Pool(2) # 2 processes
pool.map(add_hour, for_iterate.iterrows())