사용자정의 함수 사용 중 append error

조회수 581회
def show_df(column,new_colnames = ['구분'],dataframe = one):
    df = dataframe[column].value_counts().reset_index()
    new_names = new_colnames
    new_names.append('카운트수')
    df.columns = new_names
    df['비중'] = df['카운트수'].apply(lambda x : round(x/df['카운트수'].sum(),2)*100)
    return df

EDA를 진행하면서 카운트수와 비중을 계속해서 DataFrame에 넣어가면서 확인하고 싶어서 함수를 작성했습니다. 각 변수마다 구분자는 고정될 것으로 추정해서 기본값을 지정해주었는데요.
그런데 함수 내에서 append를 진행하는 과정에서
colnames 에 계속 '카운트수'가 계속 추가되어
colnames =['구분','카운트수','카운트수' ...] 형태가 되어 에러가 발생합니다.

다른 방법으로 함수를 작성하여 해결했으나
에러가 발생한 원인 및 해결책이 궁금해서 질문을 올리게되었습니다.

제가 추정하는 원인은 함수 내에서 값이 초기화 되지 않았기 때문이라고 생각했는데요.
그래서 del new_colnames, new_colnames = [] 방식으로 초기화를 해보려 했으나 먹히지 않았습니다.

혹시 어떤 이유에서 이런 상황이 발생하는 건지 알려주시면 감사하겠습니다.

1 답변

  • new_colnames 디폴트인자가 리스트형이라서, 이게 c의 static 변수처럼 이전호출 때의 결과를 계속 기억하고 있는 것 같네요.

    그리고, value_counts 에 normalize 라는 인자가 있어서, 그걸로 비중은 간단하게 구할 수 있습니다.

    >>> counts = pd.concat([df.num.value_counts(), df.num.value_counts(normalize=True)], axis=1)
    >>> counts.columns = [ 'counts', 'counts_norm' ]
    >>> counts
       counts  counts_norm
    9      10         0.20
    4       7         0.14
    1       7         0.14
    7       6         0.12
    5       5         0.10
    3       5         0.10
    8       4         0.08
    6       4         0.08
    2       2         0.04
    
    • 리스트형에 그런 속성이 있군요! 문자형을 디폴트로 받게해보니까 문제가 없네요 value_counts에 normalize기능을 모르고 있었는데 감사합니다 알 수 없는 사용자 2020.6.4 14:59
    • 정확한 내부구조는 모르겠고, 의도한 건지도 모르겠는데요. 파이썬에서는 리스트형 변수를 인자로 넘기거나 하면, 리스트 전체가 복사되어 넘어가지 않고, 레퍼런스만 넘어가고 그러잖아요. 그거랑 똑같이 디폴트인자도 인자로 주어진 리스트 자체는 전역공간 어딘가에 있고, 레퍼런스만 (내용은 초기화되지 않고) 계속 넘어가면서 이런 현상이 나타나는 것 같습니다. nowp 2020.6.4 15:21
    • 친절한 설명 감사드립니다 알 수 없는 사용자 2020.6.5 14:46

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)