Оптимизация циклов и вычислений через pandas фрейм данных, который имеет несколько операторов if - PullRequest
2 голосов
/ 09 марта 2020

Итак, у меня есть CSV-файл с тремя столбцами x, y и rank, например:

x,y,rank
153271,30622,12
143400,125936,6
153718,31606,1
19680,168350,2
99291,47206,19
39208,112928,1
97469,169684,17
...

Что я хочу сделать, это перебрать этот файл CSV и найти все координаты x и y, у которых значение rank равно 1. Затем "нарисуйте" круг вокруг каждой координаты, имеющей ранг 1, и вычислите, сколько значений попадают в этот круг. Затем я хочу вычислить все значения, которые имеют rank значение "1" внутри этого круга. Таким образом, я могу вычислить процент от количества значений «rank» «1» внутри этих кругов по сравнению с другими значениями «rank».

Мне удалось сделать это точно с помощью приведенного ниже кода, но это очень медленно. Для печати WinPercentage для каждой строки с «рангом» «1» требуется около 3 секунд. Набор данных довольно большой, однако. В нем 320 000 строк, из которых у 1/64 из них значение «rank» равно «1».

Я только начал работать с python и pandas, так что все здесь для меня совершенно ново , Мне просто интересно, будет ли более эффективный способ перебора данных. Я пробовал поискать в Google и искать в стеке, но не смог найти ничего полезного.

import csv
import pandas as pd

allDF = pd.read_csv ('players-with-rank-data.csv')
winnerDF = allDF[allDF['rank'] == 1]

def WinPercentageCalculator(allDF, winnerDF):
  radius = 20000

  for i in winnerDF.index:
    center_x = allDF.at[i,'x']
    center_y = allDF.at[i,'y']
    jumperCountInsideRadius = 0
    winnerCountInsideRadius = 0

    for row in allDF.index:
      x = allDF.at[row,'x']
      y = allDF.at[row,'y']
      dx = abs(x - center_x)
      dy = abs(-y - -center_y)

      if (dx*dx)+(dy*dy) <= (radius*radius): 
        jumperCountInsideRadius += 1
        rank = allDF.at[row,'rank']

        if rank == 1:
          winnerCountInsideRadius += 1


    winPercentage = (float(winnerCountInsideRadius) / float(jumperCountInsideRadius))
    print(str(winPercentage))


WinPercentageCalculator(allDF, winnerDF)

1 Ответ

2 голосов
/ 09 марта 2020

Это уменьшило бы почти половину сложности вашего времени @ Ode,

import csv
import pandas as pd

allDF = pd.read_csv ('players-with-rank-data.csv')
winnerDF = allDF[allDF['rank'] == 1]

radius = 20000

for i in winnerDF.index:
    center_x = allDF.at[i,'x']
    center_y = allDF.at[i,'y']

    #Check and resolve the minor changes w.r.t data, as data not visible its blind folded code
    jumperCountInsideRadius = ( allDF['x'].subtract(center_x).pow(2) + 
                                allDF['y'].subtract(center_y).pow(2)  ).lt(radius**2).sum()
    winnerCountInsideRadius = jumperCountInsideRadius.eq(1).sum()


    winPercentage = (float(winnerCountInsideRadius) / float(jumperCountInsideRadius))
    print(str(winPercentage))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...