gpt4 book ai didi

python - 有没有比 for 循环更快的方法来更改 pandas 组

转载 作者:太空宇宙 更新时间:2023-11-04 00:03:45 24 4
gpt4 key购买 nike

我正在使用下面的数据框:

这些是我试图按游戏分组的国际象棋游戏,然后根据该游戏中的移动次数对每个游戏执行功能...

        game_id     move_number colour  avg_centi
0 03gDhPWr 1 white NaN
1 03gDhPWr 2 black 37.0
2 03gDhPWr 3 white 61.0
3 03gDhPWr 4 black -5.0
4 03gDhPWr 5 white 26.0
5 03gDhPWr 6 black 31.0
6 03gDhPWr 7 white -2.0
... ... ... ... ...
110091 zzaiRa7s 34 black NaN
110092 zzaiRa7s 35 white NaN
110093 zzaiRa7s 36 black NaN
110094 zzaiRa7s 37 white NaN
110095 zzaiRa7s 38 black NaN
110096 zzaiRa7s 39 white NaN
110097 zzaiRa7s 40 black NaN

具体来说,我正在使用 pd.cut创建一个新列,game_phase ,它列出了给定的着法是否在开局、中局和残局中进行。

     game_id  move_number colour  avg_centi    phase
0 03gDhPWr 1 white NaN opening
1 03gDhPWr 2 black 37.0 opening
2 03gDhPWr 3 white 61.0 opening
3 03gDhPWr 4 black -5.0 opening
4 03gDhPWr 5 white 26.0 opening
5 03gDhPWr 6 black 31.0 opening
6 03gDhPWr 7 white -2.0 opening
.. ... ... ... ... ...
54 03gDhPWr 55 white 58.0 endgame
55 03gDhPWr 56 black 26.0 endgame
56 03gDhPWr 57 white 116.0 endgame
57 03gDhPWr 58 black 2000.0 endgame
58 03gDhPWr 59 white 0.0 endgame
59 03gDhPWr 60 black 0.0 endgame
60 03gDhPWr 61 white NaN endgame

我正在使用以下代码来实现此目的。请注意,每个游戏必须分区为 opening , middlegame , 和 endgame基于该游戏中移动的总数的箱子。

for game_id, group in df.groupby('game_id'):
bins = (0, round(group['move_number'].max() * 1/3), round(group['move_number'].max() * 2/3),
group['move_number'].max())
phases = ["opening", "middlegame", "endgame"]
try:
group.loc[:, 'phase'] = pd.cut(group['move_number'], bins, labels=phases)
except:
group.loc[:, 'phase'] = None
print(group)

问题是从数千个游戏中迭代每一个游戏需要很长时间才能找到它。

我在想一定有更快的方法来计算这个,而不是使用 for循环遍历各组并逐一执行计算。

最佳答案

这是我使用一个简单示例想出的方法。

总结一下,3 个步骤:

  1. 您可以使用 groupby 找到每个游戏的最大移动数
  2. 将新的 df 合并到旧的 df,包括 max move number
  3. 通过计算移动数/最大移动数来一次为所有游戏添加阶段

我的方法在 test1() 而你的在 test2():

import pandas
import random
import time

a = []

for group in range(25):
for count in range(random.randint(900, 1000)):
a.append({'group': chr(65 + group), 'count': count})


def test1(x):
b = pandas.DataFrame(x)

max_df = b.groupby(by='group', as_index=False)['count'].max().rename(columns={'count': 'max'})

b = pandas.merge(b, max_df, on='group', how='left')

b['phase'] = 'opening'
b.loc[b['count'] > b['max'] / 3.0, 'phase'] = 'middlegame'
b.loc[b['count'] > b['max'] / 1.5, 'phase'] = 'endgame'
b.drop('max', axis=1, inplace=True)
return b


def test2(x):
df = pandas.DataFrame(x)
df['phase'] = ''
for game_id, group in df.groupby('group'):
bins = (0, round(group['count'].max() * 1 / 3), round(group['count'].max() * 2 / 3),
group['count'].max())
phases = ["opening", "middlegame", "endgame"]
try:
group.loc[:, 'phase'] = pandas.cut(group['count'], bins, labels=phases)
except:
group.loc[:, 'phase'] = None
return df


start_time = time.time()
out1 = test1(a)
print(time.time() - start_time)

start_time = time.time()
out2 = test2(a)
print(time.time() - start_time)

assert out1.to_dict() == out2.to_dict()

这是 test1test2 快很多,尽管这只运行了 1 次:

test1: 0.09799647331237793
test2: 0.769993782043457

test2() 似乎有一些问题:它实际上并没有修改数据框,所以 phase 列是空的。不确定它是否适合您。

关于python - 有没有比 for 循环更快的方法来更改 pandas 组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54913754/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com