기록중

2021.07.16 오늘의 코드(python, pandas, numpy)

lian_is_clone 2021. 7. 16. 19:32

출근하고 부탁이 들어왔다. 엑셀로 받은 파일이 있는데 거기서 제일 매출이 높은 아이디를 찾는 일이였다.

데이터면 일단 확인부터 들어가야지 

 

품목 / 수량 / 이름 / 아이디

 

어? 아이디로 분별하면 되겠다.

아이디를 보니 aa*********로 표시되어있네... 분별 못하겠다...

그럼 어떻게 그 고객의 유니크id를 얻지?

그럼 이름이랑 아이디랑 합쳐서 유니크 아이디를 만들어야지 

정말 설마 이름이랑 아이디 앞 두자리가 같은 사람은 없겠지...

 

import pandas as pd
import numpy as np

lists = pd.read_excel('./topOfbuy.xlsx')

print(lists)

일단 불러들여야겠지 

 

그리고 이름이랑 아이디 합치고

editlist = pd.DataFrame()

editlist['품명'] = lists['품명']
editlist['수량'] = lists['수량']
editlist['이름'] = lists['이름']+lists['아이디']

이러면 이름이랑 아이디가 합쳐저 유니크가 될수 있도록 하고

 

고객이 사용한만큼 금액을 합산해야겠지

condlist = [
        (editList['품명'].str.contains(pat='프리미엄', regex=False)),
        (editList['품명'].str.contains(pat='컬러', regex=False))]
choicelist = [
        (30000 * editList['수량']),
        (25000 * editList['수량'])]
pd_sum = np.select(condlist, choicelist, default=0)

이러면 pd_sum 에는  editList['품명']에 값 조건에 따라 값 * 수량의 숫자들이 리스트화 되어있다.

 

이제 이걸 editList로 입력해야지

editList['금액'] = pd_sum

간단하게 pandas 행을 추가하는 방법 좋아

 

정보를 보면 이렇게 나온다.

          품명     수량            이름                금액
60       컬러      2        Name1bu*******     50000
626  프리미엄1  3        Name2yi*********     90000
625  프리미엄2  6        Name2yi*********    180000
239     컬러      5        Name3ja*********    125000
346     컬러     10        Name4li*******       109000
..          ...        ..                   ...                  ...
31       컬러      4        Name987ao****      100000
513  프리미엄1   6       Name898su******    180000
512  프리미엄2   6       Name898su******    180000
611  프리미엄    5        Name899ww****     150000
385      컬러      2        Name900ms****      50000

 

금액 부분은 한 row에 대해서만 계산된거기 때문에 중복된 이름으로 여러 행이 존재할 수가 있습니다.

 

이제 제가 원하는 것은 모든 구매 금액의 제일 높은사람을 찾는 것

 

유니크한 이름들 뽑아오자 

customers = editlist['이름'].unique()

 

그리고 각 이름들을 조회를 시작합시다

endList = pd.DataFrame(columns=['이름','총금액'])

컬럼만 정한 빈 객체를 만들고

for user in customers:
    users = editList[editList['이름'] == user]
    sumNum = users['금액'].sum()

    endList.loc[len(endList)] = [user,sumNum]

고객이름과 고객가 사용한 금액 총합을 구하고 

endList객체에 저장시키고 

 

제일 많이 쓴사람부터 정렬하면 

endList = endList.sort_values('총금액',ascending=False)

이제 결과를 보면 

                이름          총금액
487   Name1wo*******  900000
153    Name2ha******   810000
490    Name3ws*****    720000
139      Name4go****   480000
214    Name5js******    360000
  ..                ...              ...
197      Name898jc****   25000
434  Name899tj********  25000
24  Name900an********  25000

 

이제 전체코드

import pandas as pd
import numpy as np

lists = pd.read_excel('./topOfbuy.xlsx')

print(lists)

editList = pd.DataFrame()

editList['품명'] = lists['품명']
editList['수량'] = lists['수량']
editList['이름'] = lists['이름']+lists['아이디']

condlist = [
        (editList['품명'].str.contains(pat='프리미엄', regex=False)),
        (editList['품명'].str.contains(pat='컬러', regex=False))]
choicelist = [
        (30000 * editList['수량']),
        (25000 * editList['수량'])]
        
pd_sum = np.select(condlist, choicelist, default=0)

editList['금액'] = pd_sum

customers = editList['이름'].unique()

endList = pd.DataFrame(columns=['이름','총금액'])

for user in customers:
    users = editList[editList['이름'] == user]
    sumNum = users['금액'].sum()
    endList.loc[len(endList)] = [user,sumNum]
    
endList = endList.sort_values('총금액',ascending=False)

print(endList)

 

요걸 이제 캡슐화 해야겠지유

import pandas as pd
import openpyxl as opxl
import numpy as np

def getListChange(path,col1,col2):
    _lists = pd.read_excel(path)
    _lists[col1] = _lists[col1]+_lists[col2]
    _lists = _lists.drop(columns=[col2])
    print(_lists)
    return _lists

def twoColMultiply(data, col1,col2, list1, list2):
    condlist = [ (data[col1].str.contains(pat=requirement, regex=False)) for requirement in list1]
    choicelist = [ (list2[value] * data[col2]) for value in range(len(list1))]
    _calculator = np.select(condlist, choicelist, default=0)
    return _calculator

def allDataAdd(data,customers,col1,col2):
    _result = pd.DataFrame(columns=[col1,col2])
    for name in customers:
        _allList = data[data[col1] == name]
        total = _allList[col2].sum()

        _result.loc[len(_result)] = [name, total]
    return _result.sort_values(col2,ascending=False)


datas = getListChange('./topOfbuy.xlsx', '이름','아이디')
pays = twoColMultiply(datas, '품명', '수량', ['프리미엄','컬러'], [13900,10900])
datas['금액'] = pays
customers = datas['이름'].unique()
totalList = allDataAdd(datas, customers, '이름', '금액')

print(totalList)

임포트하면 5줄이면 결과가 도출 

거기다 

condlist = [
        (editList['품명'].str.contains(pat='프리미엄', regex=False)),
        (editList['품명'].str.contains(pat='컬러', regex=False))]
choicelist = [
        (13900 * editList['수량']),
        (10900 * editList['수량'])]

부분이 for문으로 대채되어 변형할게 많아도 리스트만 늘려주면 효율성을 높였습니다.

 

누군가 최대 매출 고객을 찾는 코드를 찾는다면

 

코드 그대로 써도 컬럼 명, 분류조건만 변경하면 추출 할 수 있다.

 

'기록중' 카테고리의 다른 글

2021.07.26 오늘의 코드  (0) 2021.07.26
2021.07.21 오늘의 코드  (0) 2021.07.21
2021.07.15 오늘의 한일  (0) 2021.07.15
2021.07.13 오늘의 한일  (0) 2021.07.13
2021.07.12 오늘의 한일  (0) 2021.07.12