웹사이트 검색

Python 3에서 pandas 및 Jupyter Notebook을 사용한 데이터 분석 및 시각화


소개

Python pandas 패키지는 데이터 조작 및 분석에 사용되며 직관적인 방식으로 레이블이 지정된 데이터 또는 관계형 데이터로 작업할 수 있도록 설계되었습니다.

pandas 패키지는 스프레드시트 기능을 제공하지만 Python으로 작업하기 때문에 기존의 그래픽 스프레드시트 프로그램보다 훨씬 빠르고 효율적입니다.

이 자습서에서는 pandasgroupby()pivot_table() 기능과 함께 작동하도록 대규모 데이터 세트를 설정하는 방법을 살펴보겠습니다. >, 마지막으로 데이터를 시각화하는 방법입니다.

pandas 패키지에 익숙해지려면 Python 3의 pandas 패키지 및 데이터 구조 소개 튜토리얼을 읽어보세요.

전제 조건

이 가이드는 로컬 데스크톱 또는 원격 서버에서 pandas의 데이터로 작업하는 방법을 다룹니다. 대규모 데이터 세트로 작업하면 메모리 집약적일 수 있으므로 두 경우 모두 이 가이드의 일부 계산을 수행하려면 컴퓨터에 최소 2GB의 메모리가 필요합니다.

이 자습서에서는 Jupyter Notebook을 사용하여 데이터 작업을 수행합니다. 아직 가지고 있지 않다면 자습서에 따라 Python 3용 Jupyter Notebook을 설치하고 설정해야 합니다.

데이터 설정

이 자습서에서는 사회 보장국 웹 사이트에서 8MB zip 파일로 제공되는 아기 이름에 대한 미국 사회 보장국 데이터로 작업할 것입니다.

올바른 디렉터리에서 서버의 Python 3 프로그래밍 환경을 활성화해 보겠습니다.

  1. cd environments
  1. . my_env/bin/activate

이제 프로젝트를 위한 새 디렉토리를 생성해 보겠습니다. 우리는 그것을 names라고 부를 수 있고 다음 디렉토리로 이동할 수 있습니다:

  1. mkdir names
  2. cd names

이 디렉토리 내에서 curl 명령을 사용하여 Social Security 웹사이트에서 zip 파일을 가져올 수 있습니다.

  1. curl -O https://www.ssa.gov/oact/babynames/names.zip

파일이 다운로드되면 사용할 모든 패키지가 설치되어 있는지 확인합니다.

  • 다차원 배열을 지원하는
  • numpy
  • matplotlib 데이터 시각화
  • 데이터 분석을 위한
  • pandas
  • seaborn은 matplotlib 통계 그래픽을 더욱 미적으로 만듭니다.

이미 설치된 패키지가 없으면 다음과 같이 pip를 사용하여 설치합니다.

  1. pip install pandas
  2. pip install matplotlib
  3. pip install seaborn

아직 numpy 패키지가 없는 경우 패키지도 설치됩니다.

이제 Jupyter Notebook을 시작할 수 있습니다.

  1. jupyter notebook

Jupyter Notebook의 웹 인터페이스에 있으면 names.zip 파일이 표시됩니다.

새 노트북 파일을 만들려면 오른쪽 상단 풀다운 메뉴에서 새로 만들기 > Python 3을 선택합니다.

그러면 노트북이 열립니다.

사용할 패키지를 가져오는 것으로 시작하겠습니다. 노트북 상단에 다음을 작성해야 합니다.

import numpy as np
import matplotlib.pyplot as pp
import pandas as pd
import seaborn

이 코드를 실행하고 ALT + ENTER를 입력하여 새 코드 블록으로 이동할 수 있습니다.

그래프를 인라인으로 유지하도록 Python Notebook에 지시해 보겠습니다.

matplotlib inline

코드를 실행하고 ALT + ENTER를 입력하여 계속 진행하겠습니다.

여기에서 zip 아카이브의 압축을 풀고 CSV 데이터 세트를 pandas에 로드한 다음 pandas DataFrames를 연결합니다.

Zip 아카이브 압축 해제

zip 아카이브를 현재 디렉터리에 압축 해제하려면 zipfile 모듈을 가져온 다음 파일 이름(이 경우 이름.zip):

import zipfile
zipfile.ZipFile('names.zip').extractall('.')

코드를 실행하고 ALT + ENTER를 입력하여 계속할 수 있습니다.

이제 names 디렉토리를 다시 살펴보면 CSV 형식의 .txt 이름 데이터 파일이 있습니다. 이 파일은 1881년부터 2015년까지 파일에 있는 데이터 연도와 일치합니다. 이러한 각 파일은 유사한 명명 규칙을 따릅니다. 예를 들어 2015년 파일은 yob2015.txt이고 1927년 파일은 yob1927.txt입니다.

이러한 파일 중 하나의 형식을 보기 위해 Python을 사용하여 하나를 열고 맨 위 5줄을 표시해 보겠습니다.

open('yob2015.txt','r').readlines()[:5]

코드를 실행하고 ALT + ENTER를 계속 누릅니다.

Output
['Emma,F,20355\n', 'Olivia,F,19553\n', 'Sophia,F,17327\n', 'Ava,F,16286\n', 'Isabella,F,15504\n']

데이터 형식이 지정되는 방식은 이름이 먼저(Emma 또는 Olivia에서와 같이), 다음으로 성별(여성 이름의 경우 F에서와 같이 < 남자 이름은M), 그 해에 그 이름으로 태어난 아기의 수(2015년에 태어난 Emma라는 이름의 아기는 20,355명)입니다.

이 정보를 사용하여 pandas에 데이터를 로드할 수 있습니다.

pandas에 CSV 데이터 로드

쉼표로 구분된 값 데이터를 pandas에 로드하기 위해 pd.read_csv() 함수를 사용하여 텍스트 파일의 이름과 결정한 열 이름을 전달합니다. 에. 2015년 출생 파일의 데이터를 사용하므로 이 경우 names2015를 변수에 할당합니다.

names2015 = pd.read_csv('yob2015.txt', names = ['Name', 'Sex', 'Babies'])

ALT + ENTER를 입력하여 코드를 실행하고 계속하십시오.

제대로 작동하는지 확인하기 위해 테이블 상단을 표시해 보겠습니다.

names2015.head()

코드를 실행하고 ALT + ENTER를 계속 누르면 다음과 같은 출력이 표시됩니다.

이제 테이블에는 각 이름으로 태어난 아기의 이름, 성별 및 수에 대한 정보가 열별로 정리되어 있습니다.

팬더 개체 연결

pandas 개체를 연결하면 names 디렉토리 내의 모든 개별 텍스트 파일로 작업할 수 있습니다.

이들을 연결하려면 먼저 채워지지 않은 목록 데이터 유형에 변수를 할당하여 목록을 초기화해야 합니다.

all_years = []

그런 다음 for 루프를 사용하여 1880-2015년 범위의 모든 파일을 반복합니다. 2015년이 루프에 포함되도록 2015년 끝에 +1을 추가합니다.

all_years = []

for year in range(1880, 2015+1):

루프 내에서 각 파일의 다른 이름을 처리하기 위해 문자열 포맷터를 사용하여 각 텍스트 파일 값 목록에 추가합니다. 해당 값을 year 변수에 전달합니다. 다시 이름, 성별아기 수에 대한 열을 지정합니다.

all_years = []

for year in range(1880, 2015+1):
    all_years.append(pd.read_csv('yob{}.txt'.format(year),
                                 names = ['Name', 'Sex', 'Babies']))

또한 각 연도에 대한 열을 생성하여 순서를 유지합니다. 루프가 진행될 때 -1의 인덱스를 사용하여 각 반복 후에 이를 가리킬 수 있습니다.

all_years = []

for year in range(1880, 2015+1):
    all_years.append(pd.read_csv('yob{}.txt'.format(year),
                                 names = ['Name', 'Sex', 'Babies']))
    all_years[-1]['Year'] = year

마지막으로 pd.concat() 함수를 사용하여 연결하여 pandas 개체에 추가합니다. 이 정보를 저장하기 위해 all_names 변수를 사용할 것입니다.

all_years = []

for year in range(1880, 2015+1):
    all_years.append(pd.read_csv('yob{}.txt'.format(year),
                                 names = ['Name', 'Sex', 'Babies']))
    all_years[-1]['Year'] = year

all_names = pd.concat(all_years)

이제 ALT + ENTER를 사용하여 루프를 실행한 다음 결과 테이블의 꼬리(맨 아래 행)를 호출하여 출력을 검사할 수 있습니다.

all_names.tail()

이제 데이터 세트가 완성되었으며 pandas에서 추가 작업을 수행할 준비가 되었습니다.

데이터 그룹화

pandas를 사용하면 .groupby() 함수를 사용하여 열별로 데이터를 그룹화할 수 있습니다. 전체 데이터 세트에 all_names 변수를 사용하면 groupby()를 사용하여 데이터를 여러 버킷으로 분할할 수 있습니다.

성별과 연도별로 데이터 세트를 그룹화해 보겠습니다. 다음과 같이 설정할 수 있습니다.

group_name = all_names.groupby(['Sex', 'Year'])

코드를 실행하고 ALT + ENTER를 계속 사용할 수 있습니다.

이 시점에서 group_name 변수를 호출하면 다음과 같은 결과가 표시됩니다.

Output
<pandas.core.groupby.DataFrameGroupBy object at 0x1187b82e8>

이는 DataFrameGroupBy 개체임을 보여줍니다. 이 개체에는 데이터를 그룹화하는 방법에 대한 지침이 있지만 값을 표시하는 방법에 대한 지침은 제공하지 않습니다.

값을 표시하려면 지침을 제공해야 합니다. 예를 들어 .size(), .mean().sum()을 계산하여 테이블을 반환할 수 있습니다.

.size()부터 시작하겠습니다.

group_name.size()

코드를 실행하고 ALT + ENTER를 계속 누르면 다음과 같이 출력됩니다.

Output
Sex Year F 1880 942 1881 938 1882 1028 1883 1054 1884 1172 ...

이 데이터는 좋아 보이지만 더 읽기 쉽습니다. .unstack 함수를 추가하여 더 읽기 쉽게 만들 수 있습니다.

group_name.size().unstack()

이제 코드를 실행하고 ALT + ENTER를 입력하여 계속하면 출력은 다음과 같습니다.

이 데이터가 알려주는 것은 매년 얼마나 많은 여성 이름과 남성 이름이 있었는지입니다. 예를 들어 1889년에는 1,479개의 여성 이름과 1,111개의 남성 이름이 있었습니다. 2015년에는 18,993개의 여성 이름과 13,959개의 남성 이름이 있었습니다. 이것은 시간이 지남에 따라 이름에 더 큰 다양성이 있음을 보여줍니다.

태어난 아기의 총 수를 얻으려면 .sum() 함수를 사용할 수 있습니다. 이전에 생성한 단일 yob2015.txt 파일에서 설정한 names2015인 더 작은 데이터 세트에 이를 적용해 보겠습니다.

names2015.groupby(['Sex']).sum()

ALT + ENTER를 입력하여 코드를 실행하고 계속 진행해 보겠습니다.

이것은 2015년에 태어난 남녀 아기의 총 수를 보여주지만, 그 해에 이름이 5번 이상 사용된 아기만 데이터 세트에 포함됩니다.

pandas .groupby() 함수를 사용하면 데이터를 의미 있는 그룹으로 나눌 수 있습니다.

피벗 테이블

피벗 테이블은 데이터를 요약하는 데 유용합니다. 한 테이블에 저장된 데이터를 자동으로 정렬, 계산, 합계 또는 평균화할 수 있습니다. 그런 다음 요약된 데이터의 새 테이블에 해당 작업의 결과를 표시할 수 있습니다.

pandas에서 pivot_table() 함수는 피벗 테이블을 만드는 데 사용됩니다.

피벗 테이블을 구성하려면 먼저 작업할 DataFrame을 호출한 다음 표시하려는 데이터 및 그룹화 방법을 호출합니다.

이 예에서는 all_names 데이터로 작업하고 한 차원에서는 이름으로, 다른 차원에서는 연도별로 그룹화된 아기 데이터를 표시합니다.

pd.pivot_table(all_names, 'Babies', 'Name', 'Year')

ALT + ENTER를 입력하여 코드를 실행하고 계속하면 다음과 같은 결과가 표시됩니다.

빈 값이 많이 표시되기 때문에 한 경우에는 행으로, 다른 경우에는 열로 이름과 연도를 열로 유지하려고 할 수 있습니다. 데이터를 대괄호로 그룹화하면 됩니다.

pd.pivot_table(all_names, 'Babies', ['Name', 'Year'])

ALT + ENTER를 입력하여 코드를 실행하고 계속하면 이 테이블은 이제 각 이름에 대해 기록된 연도의 데이터만 표시합니다.

Output
Name Year Aaban 2007 5.0 2009 6.0 2010 9.0 2011 11.0 2012 11.0 2013 14.0 2014 16.0 2015 15.0 Aabha 2011 7.0 2012 5.0 2014 9.0 2015 7.0 Aabid 2003 5.0 Aabriella 2008 5.0 2014 5.0 2015 5.0

또한 다음과 같이 데이터를 그룹화하여 이름과 성별을 한 차원으로, 연도를 다른 차원으로 지정할 수 있습니다.

pd.pivot_table(all_names, 'Babies', ['Name', 'Sex'], 'Year')

코드를 실행하고 ALT + ENTER를 계속 누르면 다음 표가 표시됩니다.

피벗 테이블을 사용하면 기존 테이블에서 새 테이블을 만들어 해당 데이터를 그룹화하는 방법을 결정할 수 있습니다.

데이터 시각화

matplotlib와 같은 다른 패키지와 함께 pandas를 사용하면 노트북 내에서 데이터를 시각화할 수 있습니다.

우리는 수년 동안 주어진 이름의 인기도에 대한 데이터를 시각화할 것입니다. 그러기 위해서는 특정 이름의 변화하는 인기를 볼 수 있는 데이터를 재작업하기 위해 인덱스를 설정하고 정렬해야 합니다.

pandas 패키지를 사용하면 임의의 차원 수로 데이터를 저장하고 조작할 수 있는 계층적 또는 다단계 인덱싱을 수행할 수 있습니다.

성별, 이름, 연도에 대한 정보로 데이터를 인덱싱할 것입니다. 또한 인덱스를 정렬하려고 합니다.

all_names_index = all_names.set_index(['Sex','Name','Year']).sort_index()

ALT + ENTER를 입력하여 실행하고 다음 줄로 계속 진행하면 노트북에 새 인덱스 DataFrame이 표시됩니다.

all_names_index

코드를 실행하고 ALT + ENTER를 계속 누르면 출력이 다음과 같이 표시됩니다.

다음으로 시간이 지남에 따라 이름의 인기도를 표시하는 함수를 작성하려고 합니다. name_plot 함수를 호출하고 sexname을 함수를 실행할 때 호출할 매개 변수로 전달합니다.

def name_plot(sex, name):

이제 우리가 만든 테이블을 보관할 data라는 변수를 설정합니다. 인덱스 값으로 행을 선택하기 위해 pandas DataFrame loc도 사용할 것입니다. 우리의 경우 locsexname 데이터를 모두 참조하는 MultiIndex의 필드 조합을 기반으로 하길 원할 것입니다. .

이 구성을 함수에 작성해 보겠습니다.

def name_plot(sex, name):
    data = all_names_index.loc[sex, name]

마지막으로 pp로 가져온 matplotlib.pyplot 을 사용하여 값을 플롯하려고 합니다. 그런 다음 성별 및 이름 데이터의 값을 지수(우리의 목적상 연도)에 대해 플로팅합니다.

def name_plot(sex, name):
    data = all_names_index.loc[sex, name]
    
    pp.plot(data.index, data.values)

ALT + ENTER를 입력하여 실행하고 다음 셀로 이동합니다. 이제 주어진 이름이 Danica인 여성 이름의 경우 F와 같이 선택한 성별과 이름으로 함수를 호출할 수 있습니다.

name_plot('F', 'Danica')

지금 ALT + ENTER를 입력하면 다음과 같은 결과가 표시됩니다.

사용 중인 시스템에 따라 글꼴 대체에 대한 경고가 표시될 수 있지만 데이터는 여전히 올바르게 표시됩니다.

비주얼리제이션을 보면 Danica라는 여성 이름의 인기가 1990년경에 약간 상승했으며 2010년 직전에 최고조에 달했음을 알 수 있습니다.

우리가 만든 함수는 여러 이름에서 시간 경과에 따른 추세를 볼 수 있도록 둘 이상의 이름에서 데이터를 그리는 데 사용할 수 있습니다.

플롯을 조금 더 크게 만들어 보겠습니다.

pp.figure(figsize = (18, 8))

다음으로 플롯하려는 모든 이름이 있는 목록을 생성해 보겠습니다.

pp.figure(figsize = (18, 8))

names = ['Sammy', 'Jesse', 'Drew', 'Jamie']

이제 for 루프를 사용하여 목록을 반복하고 각 이름에 대한 데이터를 그릴 수 있습니다. 먼저 다음 성 중립적 이름을 여성 이름으로 사용해 보겠습니다.

pp.figure(figsize = (18, 8))

names = ['Sammy', 'Jesse', 'Drew', 'Jamie']

for name in names:
    name_plot('F', name)

이 데이터를 더 쉽게 이해할 수 있도록 범례를 포함해 보겠습니다.

pp.figure(figsize = (18, 8))

names = ['Sammy', 'Jesse', 'Drew', 'Jamie']

for name in names:
    name_plot('F', name)
    
pp.legend(names)

ALT + ENTER를 입력하여 코드를 실행하고 계속하면 다음과 같은 결과가 표시됩니다.

각각의 이름이 여성 이름으로 서서히 인기를 얻고 있는 가운데 제이미라는 이름은 1980년경 여성 이름으로 압도적인 인기를 끌었다.

이름은 같지만 이번에는 남성 이름으로 플롯해 보겠습니다.

pp.figure(figsize = (18, 8))

names = ['Sammy', 'Jesse', 'Drew', 'Jamie']

for name in names:
    name_plot('M', name)
    
pp.legend(names)

다시 ALT + ENTER를 입력하여 코드를 실행하고 계속합니다. 그래프는 다음과 같이 표시됩니다.

이 데이터는 Jesse가 일반적으로 가장 인기 있는 선택이며 특히 1980년대와 1990년대에 인기가 있는 이름을 통해 더 많은 인기를 보여줍니다.

여기에서 계속해서 이름 데이터를 가지고 놀고, 다양한 이름과 인기도에 대한 시각화를 만들고, 다른 스크립트를 만들어 다른 데이터를 보고 시각화할 수 있습니다.

결론

이 자습서에서는 데이터 설정에서 groupby()pivot_table()로 데이터를 그룹화하고 MultiIndex 및 matplotlib 패키지를 사용하여 pandas 데이터 시각화.

많은 조직과 기관에서 pandas 및 데이터 시각화에 대해 계속 학습하는 데 사용할 수 있는 데이터 세트를 제공합니다. 예를 들어 미국 정부는 data.gov를 통해 데이터를 제공합니다.

Python 3에서 matplotlib를 사용하여 단어 빈도를 그래프로 작성하는 방법 가이드를 따라 matplotlib로 데이터를 시각화하는 방법에 대해 자세히 알아볼 수 있습니다.