Оптимизация кода для группировки по уникальному человеку - PullRequest
0 голосов
/ 14 мая 2019

У меня есть файл с транзакциями. Каждая транзакция включает в себя идентификаторы личности (которые иногда / часто отсутствуют) и данные транзакции. Идентификаторы личности: имя, имя, телефон, адрес электронной почты и номер социального страхования. Я хочу связать каждую транзакцию с уникальным человеком. В качестве бизнес-правила я установил, что две транзакции принадлежат одному и тому же лицу, если fname и lname идентичны И, по крайней мере, один из трех идентификаторов других лиц идентичен. В результате мне нужно иметь два фрейма данных (и, в конечном итоге, два файла CSV): один с уникальными людьми и одна копия исходных данных с дополнительным столбцом для идентификатора человека.

Я написал код, который очень хорошо работает для решения проблемы. За исключением того, что когда фильмы становятся действительно длинными (я говорю о сотнях тысяч строк), они застревают. Я почти уверен, что мой код не оптимизирован, и я думаю, что могу найти лучший способ, используя функции agreggate, такие как groupby () или unique (), которые, на мой взгляд, гораздо быстрее. Но я не могу понять, как.

import pandas as pd
workDir=r"D:\fichiers\perso\perso\python\unicity\\"


sourceFile='rawdata.csv'
inFrame=pd.read_csv(workDir+sourceFile, sep=";",encoding='ISO-8859-1')
personFrame=pd.DataFrame(columns=('id','fname','lname','email', 'phone','social security number'))
outFrame=pd.DataFrame(columns=inFrame.columns)
idPerson=0
#print(inFrame)


def samePerson(p1, p2):
  response=0
  if p1['fname']==p2['fname'] and p1['lname']==p2['lname']:
      if p1['email']==p2['email'] or p1['phone']==p2['phone'] or p1['social security number']==p2['social security number']:
        response=1
  return(response)

def completePerson(old, new):
    #complete with new line missing data in ols version of the person
    for theColumn in ('fname','lname','email', 'phone','social security number'):
        if pd.isnull(old[theColumn]) :
            old [theColumn]=new[theColumn]
    return(old)

def processLine(theLine):
  global personFrame
  global idPerson
  global outFrame
  theFlag=0
  for indexPerson, thePerson in personFrame.iterrows(): 
      if theFlag==0:
          if samePerson(theLine,thePerson):
              theLine['idPerson']=thePerson.idPerson
              personFrame.loc[indexPerson]=completePerson(thePerson, theLine)
              theFlag=1
  if theFlag==0:
      theLine['idPerson']=idPerson
      idPerson=idPerson+1
      personFrame=personFrame.append(theLine)
  outFrame=outFrame.append(theLine)


def processdf():
    inFrame.apply(processLine, axis=1)
    with open(workDir+'persons.csv','w', encoding='ISO-8859-1') as f:
        personFrame.to_csv(f, index='false')
    with open(workDir+'transactionss.csv','w', encoding='ISO-8859-1') as f:
        outFrame.to_csv(f, index='false')

processdf()
...