{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# 연속적으로 값을 출력\n", "# from IPython.core.interactiveshell import InteractiveShell\n", "# InteractiveShell.ast_node_interactivity = \"last_expr\"\n", "from IPython.display import display" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Pandas\n", "- NumPy를 기반으로 만들어진 새로운 패키지\n", "- **DataFrame**이라는 효율적인 자료구조를 제공\n", " - 행과 열 레이블이 부착된 다차원 배열\n", " - 여러 가지 타입의 데이터를 가질 수 있으며 데이터 누락도 허용(NaN)\n", "- 레이블이 붙은 데이터를 위한 편리한 스토리지 인터페이스를 제공\n", "- 데이터베이스 프레임워크와 스프레드시트 프로그램 사용자에게 익숙한 강력한 데이터 연산을 구현" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pandas 객체\n", "- 행과 열이 단순 정수형 인덱스가 아닌 **레이블**로 식별되는 NumPy의 (구조화된) 배열을 보강한 버전\n", "- Pandas의 세 가지 기본 자료구조\n", " - Series\n", " - DataFrame\n", " - Index" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# NumPy와 Pandas를 import 한다.\n", "import numpy as np\n", "import pandas as pd" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Pandas Series 객체\n", " - 인덱싱된 데이터의 1차원 배열이다." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 0.25\n", "1 0.50\n", "2 0.75\n", "3 1.00\n", "dtype: float64" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data = pd.Series([0.25, 0.5, 0.75, 1.0])\n", "data" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0.25, 0.5 , 0.75, 1. ])" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Series의 values에 접근하기\n", "data.values" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "RangeIndex(start=0, stop=4, step=1)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Series의 index에 접근하기\n", "data.index" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.5" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# index를 이용하여 Series의 value에 접근하기\n", "data[1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **일반화된 NumPy 배열**\n", "> - NumPy 배열에는 값에 접근하는 데 사용되는 암묵적으로 정의된 정수형 인덱스가 존재\n", "> - Pandas Series에는 값에 연결된 **명시적**으로 정의된 인덱스가 존재" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 0.25\n", "b 0.50\n", "c 0.75\n", "d 1.00\n", "dtype: float64" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data = pd.Series([0.25, 0.5, 0.75, 1.0], index=['a', 'b', 'c', 'd'])\n", "data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **특수한 딕셔너리**\n", "> - 딕셔너리는 일련의 임의의 값에 임의의 키를 매핑하는 구조\n", "> - Series는 타입이 지정된 키를 일련의 타입이 지정된 값에 매핑하는 구조 " ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Florida 19552860\n", "Illinois 12882135\n", "New York 19651127\n", "Texas 26448193\n", "california 38332521\n", "dtype: int64" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "population_dict = {'california': 38332521,\n", " 'Texas': 26448193,\n", " 'New York': 19651127,\n", " 'Florida': 19552860,\n", " 'Illinois': 12882135}\n", "\n", "# Series의 생성자로 딕셔너리를 넣는다.\n", "population = pd.Series(population_dict)\n", "\n", "population" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **Series 객체 구성하기**" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 2\n", "1 4\n", "2 6\n", "dtype: int64" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# data가 리스트나 NumPy 배열일 수 있고, 그런 경우 index는 정수가 기본\n", "pd.Series([2, 4, 6])" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "100 5\n", "200 5\n", "300 5\n", "dtype: int64" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# data는 지정된 인덱스를 채우기 위새 반복되는 스칼라값일 수 있다.\n", "pd.Series(5, index=[100, 200, 300])" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1 b\n", "2 a\n", "3 c\n", "dtype: object" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# data가 딕셔너리일때, 이 경우 index는 기본적으로 딕셔너리 키를 정렬해서 취한다.\n", "pd.Series({2:'a', 1:'b', 3:'c'})" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3 c\n", "2 a\n", "dtype: object" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# data가 딕셔너리일때, index를 명시적으로 설정할 수 있다.\n", "pd.Series({2:'a', 1:'b', 3:'c'}, index=[3, 2])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Pandas DataFrame 객체" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **일반화된 NumPy 배열**\n", "> - 유연한 **행 인덱스**와 유연한 **열 이름**을 가진 2차원 배열\n", "> - 정렬된 Series 객체의 연속으로 볼 수 있다. (정렬 : 같은 인덱스를 공유한다!)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Florida 170312\n", "Illinois 149995\n", "New York 141297\n", "Texas 695662\n", "california 423967\n", "dtype: int64" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "area_dict = {'california': 423967,\n", " 'Texas': 695662,\n", " 'New York': 141297,\n", " 'Florida': 170312,\n", " 'Illinois': 149995}\n", "\n", "# 딕셔너리의 키를 기준으로 정렬해서 보여준다.\n", "area = pd.Series(area_dict)\n", "area" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Florida 19552860\n", "Illinois 12882135\n", "New York 19651127\n", "Texas 26448193\n", "california 38332521\n", "dtype: int64" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "population_dict = {'california': 38332521,\n", " 'Texas': 26448193,\n", " 'New York': 19651127,\n", " 'Florida': 19552860,\n", " 'Illinois': 12882135}\n", "\n", "population = pd.Series(population_dict)\n", "population" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
areapopulation
Florida17031219552860
Illinois14999512882135
New York14129719651127
Texas69566226448193
california42396738332521
\n", "
" ], "text/plain": [ " area population\n", "Florida 170312 19552860\n", "Illinois 149995 12882135\n", "New York 141297 19651127\n", "Texas 695662 26448193\n", "california 423967 38332521" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Series 객체 2개를 이용하여 DataFrame을 생성한다. key는 'population', 'area'가 되며 열 인덱스가 된다.\n", "# 두 개의 Series가 공통으로 가지고 있던 key 이름이 행 인덱스가 된다.\n", "states = pd.DataFrame({'population': population,\n", " 'area':area})\n", "\n", "states" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['Florida', 'Illinois', 'New York', 'Texas', 'california'], dtype='object')" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 인덱스 레이블에 접근\n", "states.index" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['area', 'population'], dtype='object')" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 열 레이블에 접근\n", "states.columns" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **특수한 딕셔너리**\n", "> - 열 이름을 열 데이터로 이뤄진 Series에 매핑" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Florida 170312\n", "Illinois 149995\n", "New York 141297\n", "Texas 695662\n", "california 423967\n", "Name: area, dtype: int64" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "states['area']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **DataFrame 객체 구성하기**" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
population
Florida19552860
Illinois12882135
New York19651127
Texas26448193
california38332521
\n", "
" ], "text/plain": [ " population\n", "Florida 19552860\n", "Illinois 12882135\n", "New York 19651127\n", "Texas 26448193\n", "california 38332521" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"단일 Series 객체에서 구성하기\"\"\"\n", "\n", "pd.DataFrame(population, columns=['population'])" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[{'a': 0, 'b': 0}, {'a': 1, 'b': 2}, {'a': 2, 'b': 4}]" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ab
000
112
224
\n", "
" ], "text/plain": [ " a b\n", "0 0 0\n", "1 1 2\n", "2 2 4" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"딕셔너리의 리스트에서 구성하기\"\"\"\n", "\n", "data = [{'a': i, 'b': 2*i} for i in range(3)]\n", "display(data)\n", "\n", "pd.DataFrame(data)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'a': [1, 2, 3], 'b': [4, 5, 6]}" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ab
014
125
236
\n", "
" ], "text/plain": [ " a b\n", "0 1 4\n", "1 2 5\n", "2 3 6" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"딕셔너리로 구성하기\"\"\"\n", "\n", "data = {'a': [1, 2, 3], 'b': [4, 5, 6]}\n", "display(data)\n", "\n", "pd.DataFrame(data)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
areapopulation
Florida17031219552860
Illinois14999512882135
New York14129719651127
Texas69566226448193
california42396738332521
\n", "
" ], "text/plain": [ " area population\n", "Florida 170312 19552860\n", "Illinois 149995 12882135\n", "New York 141297 19651127\n", "Texas 695662 26448193\n", "california 423967 38332521" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"Series 객체의 딕셔너리에 구성하기\"\"\"\n", "\n", "print(type(population))\n", "print(type(area))\n", "\n", "pd.DataFrame({'population': population, 'area': area})" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([(0, 0.), (0, 0.), (0, 0.)], dtype=[('A', '\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AB
000.0
100.0
200.0
\n", "" ], "text/plain": [ " A B\n", "0 0 0.0\n", "1 0 0.0\n", "2 0 0.0" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"NumPy의 구조화된 배열에서 구성하기\"\"\"\n", "\n", "a = np.zeros(3, dtype = [('A', 'i8'), ('B','f8')])\n", "display(a)\n", "\n", "pd.DataFrame(a)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
abc
01.02NaN
1NaN23.0
\n", "
" ], "text/plain": [ " a b c\n", "0 1.0 2 NaN\n", "1 NaN 2 3.0" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 딕셔너리의 일부 키가 누락되더라도 Padnas는 NaN 값으로 채운다. (Not A Number)\n", "pd.DataFrame([{'a': 1, 'b': 2}, {'b': 2, 'c': 3}])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Pandas Index 객체\n", "- 불변의 배열이나 정렬된 집합" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **불변의 배열**" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Int64Index([2, 3, 5, 7, 11], dtype='int64')" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "idx = pd.Index([2, 3, 5, 7, 11])\n", "idx" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "Int64Index([2, 5, 11], dtype='int64')" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(idx[1])\n", "display(idx[::2]) # Slicing" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "(5,)" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "1" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "dtype('int64')" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# NumPy 배열에서 익숙한 속성들\n", "display(idx.size)\n", "display(idx.shape)\n", "display(idx.ndim)\n", "display(idx.dtype)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "Index does not support mutable operations", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# 일반적인 방법으로는 변경될 수 없다. 즉 Immutable 하다.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0midx\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m/anaconda3/lib/python3.6/site-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36m__setitem__\u001b[0;34m(self, key, value)\u001b[0m\n\u001b[1;32m 1722\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1723\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__setitem__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1724\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Index does not support mutable operations\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1725\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1726\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__getitem__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mTypeError\u001b[0m: Index does not support mutable operations" ] } ], "source": [ "# 일반적인 방법으로는 변경될 수 없다. 즉 Immutable 하다.\n", "idx[1] = 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **정렬된 집합**\n", ">- 파이썬에 내장된 set 데이터 구조에서 사용하는 표기법을 따른다." ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Int64Index([3, 5, 7], dtype='int64')" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "Int64Index([1, 2, 3, 5, 7, 9, 11], dtype='int64')" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "Int64Index([1, 2, 9, 11], dtype='int64')" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "idx_A = pd.Index([1, 3, 5, 7, 9])\n", "idx_B = pd.Index([2, 3, 5, 7, 11])\n", "\n", "# 교집합\n", "display(idx_A & idx_B)\n", "\n", "# 합집합\n", "display(idx_A | idx_B)\n", "\n", "# 여집합\n", "display(idx_A ^ idx_B)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 데이터 인덱싱과 선택" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Series에서 데이터 선택" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **Series: 딕셔너리**" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a 0.25\n", "b 0.50\n", "c 0.75\n", "d 1.00\n", "dtype: float64\n", "0.5\n" ] } ], "source": [ "data = pd.Series([0.25, 0.5, 0.75, 1.0], index = ['a', 'b', 'c', 'd'])\n", "\n", "print(data)\n", "print(data['b'])" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 키의 포함 유무를 체크해보자\n", "'a' in data" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['a', 'b', 'c', 'd'], dtype='object')" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 키집합\n", "data.keys()" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 0.25\n", "b 0.50\n", "c 0.75\n", "d 1.00\n", "e 1.25\n", "dtype: float64" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 새로운 값 추가\n", "data['e'] = 1.25\n", "data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **Series: 1차원 배열**" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 0.25\n", "b 0.50\n", "c 0.75\n", "d 1.00\n", "e 1.25\n", "dtype: float64" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 0.25\n", "b 0.50\n", "c 0.75\n", "dtype: float64" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"명시적인 인덱스로 슬라이싱하기\"\"\"\n", "\n", "# Python 컬렉션, NumPy 배열에서와는 달리 마지막 인덱스가 포함된다.\n", "data['a':'c']" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 0.25\n", "b 0.50\n", "dtype: float64" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"암묵적 정수 인덱스로 슬라이싱하기\"\"\"\n", "\n", "# 마지막 인덱스는 포함되지 않는다.\n", "data[0:2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### Masking" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a False\n", "b True\n", "c True\n", "d True\n", "e True\n", "dtype: bool" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data > 0.3" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a True\n", "b True\n", "c True\n", "d False\n", "e False\n", "dtype: bool" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data < 0.8" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a False\n", "b True\n", "c True\n", "d False\n", "e False\n", "dtype: bool" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(data > 0.3) & (data < 0.8)" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "b 0.50\n", "c 0.75\n", "dtype: float64" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data[(data > 0.3) & (data < 0.8)]" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 0.25\n", "e 1.25\n", "dtype: float64" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"Fancy 인덱싱\"\"\"\n", "\n", "data[['a', 'e']]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### DataFrame에서 데이터 선택" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Florida 19552860\n", "Illinois 12882135\n", "New York 19651127\n", "Texas 26448193\n", "california 38332521\n", "dtype: int64" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "pandas.core.series.Series" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# 미국의 population\n", "display(population)\n", "display(type(population))" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Florida 170312\n", "Illinois 149995\n", "New York 141297\n", "Texas 695662\n", "california 423967\n", "dtype: int64" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "pandas.core.series.Series" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# 미국의 area\n", "display(area)\n", "display(type(area))" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
areapopulation
Florida17031219552860
Illinois14999512882135
New York14129719651127
Texas69566226448193
california42396738332521
\n", "
" ], "text/plain": [ " area population\n", "Florida 170312 19552860\n", "Illinois 149995 12882135\n", "New York 141297 19651127\n", "Texas 695662 26448193\n", "california 423967 38332521" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data = pd.DataFrame({'population': population, 'area': area})\n", "data" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Florida 170312\n", "Illinois 149995\n", "New York 141297\n", "Texas 695662\n", "california 423967\n", "Name: area, dtype: int64" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 열 이름으로 된 딕셔너리 스타일의 인덱싱을 통해 접근\n", "data['area']" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Florida 170312\n", "Illinois 149995\n", "New York 141297\n", "Texas 695662\n", "california 423967\n", "Name: area, dtype: int64" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 열 이름을 이용해 속성 스타일로 접근\n", "data.area" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
areapopulationdensity
Florida17031219552860114.806121
Illinois1499951288213585.883763
New York14129719651127139.076746
Texas6956622644819338.018740
california4239673833252190.413926
\n", "
" ], "text/plain": [ " area population density\n", "Florida 170312 19552860 114.806121\n", "Illinois 149995 12882135 85.883763\n", "New York 141297 19651127 139.076746\n", "Texas 695662 26448193 38.018740\n", "california 423967 38332521 90.413926" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 새로운 열을 추가 (NumPy의 ufunc의 벡터화 연산)\n", "data['density'] = data['population'] / data['area']\n", "data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **DataFrame: 2차원 배열**" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1.70312000e+05, 1.95528600e+07, 1.14806121e+02],\n", " [1.49995000e+05, 1.28821350e+07, 8.58837628e+01],\n", " [1.41297000e+05, 1.96511270e+07, 1.39076746e+02],\n", " [6.95662000e+05, 2.64481930e+07, 3.80187404e+01],\n", " [4.23967000e+05, 3.83325210e+07, 9.04139261e+01]])" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 데이터 배열\n", "data.values" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
FloridaIllinoisNew YorkTexascalifornia
area1.703120e+051.499950e+051.412970e+056.956620e+054.239670e+05
population1.955286e+071.288214e+071.965113e+072.644819e+073.833252e+07
density1.148061e+028.588376e+011.390767e+023.801874e+019.041393e+01
\n", "
" ], "text/plain": [ " Florida Illinois New York Texas \\\n", "area 1.703120e+05 1.499950e+05 1.412970e+05 6.956620e+05 \n", "population 1.955286e+07 1.288214e+07 1.965113e+07 2.644819e+07 \n", "density 1.148061e+02 8.588376e+01 1.390767e+02 3.801874e+01 \n", "\n", " california \n", "area 4.239670e+05 \n", "population 3.833252e+07 \n", "density 9.041393e+01 " ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 행과 열을 바꾸기 (Transpose)\n", "data.T" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "암묵적 정수 인덱스 (area는 0, population은 1, density는 2)를 이용해서 행으로 접근 가능" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([1.70312000e+05, 1.95528600e+07, 1.14806121e+02])" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 첫번째 행에 접근. values를 이용하였음을 기억하라. 즉 data[0]이 아니다. Florida 데이터에 접근.\n", "data.values[0]" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Florida 170312\n", "Illinois 149995\n", "New York 141297\n", "Texas 695662\n", "california 423967\n", "Name: area, dtype: int64" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 열에 접근\n", "data['area']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **추가적인 인덱싱 규칙**" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Florida 170312\n", "Illinois 149995\n", "New York 141297\n", "Texas 695662\n", "california 423967\n", "Name: area, dtype: int64" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# 인덱싱은 열을 참조\n", "display(data['area'])" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "ename": "KeyError", "evalue": "'Florida'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m/anaconda3/lib/python3.6/site-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 2524\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2525\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2526\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n", "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n", "\u001b[0;31mKeyError\u001b[0m: 'Florida'", "\nDuring handling of the above exception, another exception occurred:\n", "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# 행을 참조해보자. 행에 접근하기 위해서는 암묵적 정수 index를 사용한다.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mdisplay\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Florida'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m/anaconda3/lib/python3.6/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 2137\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_getitem_multilevel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2138\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2139\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_getitem_column\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2140\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2141\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_getitem_column\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/anaconda3/lib/python3.6/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m_getitem_column\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 2144\u001b[0m \u001b[0;31m# get column\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2145\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_unique\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2146\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_item_cache\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2147\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2148\u001b[0m \u001b[0;31m# duplicate columns & possible reduce dimensionality\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/anaconda3/lib/python3.6/site-packages/pandas/core/generic.py\u001b[0m in \u001b[0;36m_get_item_cache\u001b[0;34m(self, item)\u001b[0m\n\u001b[1;32m 1840\u001b[0m \u001b[0mres\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcache\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1841\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mres\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1842\u001b[0;31m \u001b[0mvalues\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_data\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1843\u001b[0m \u001b[0mres\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_box_item_values\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalues\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1844\u001b[0m \u001b[0mcache\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mres\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/anaconda3/lib/python3.6/site-packages/pandas/core/internals.py\u001b[0m in \u001b[0;36mget\u001b[0;34m(self, item, fastpath)\u001b[0m\n\u001b[1;32m 3841\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3842\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0misna\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3843\u001b[0;31m \u001b[0mloc\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3844\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3845\u001b[0m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0misna\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/anaconda3/lib/python3.6/site-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 2525\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2526\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2527\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_maybe_cast_indexer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2528\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2529\u001b[0m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_indexer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mmethod\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtolerance\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtolerance\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n", "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n", "\u001b[0;31mKeyError\u001b[0m: 'Florida'" ] } ], "source": [ "# 행을 참조해보자. 행에 접근하기 위해서는 암묵적 정수 index를 사용한다.\n", "display(data['Florida'])" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
areapopulationdensity
Florida17031219552860114.806121
Illinois1499951288213585.883763
\n", "
" ], "text/plain": [ " area population density\n", "Florida 170312 19552860 114.806121\n", "Illinois 149995 12882135 85.883763" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 슬라이싱은 행을 참조 (헷갈리지 말자.)\n", "data['Florida': 'Illinois']" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
areapopulationdensity
california4239673833252190.413926
\n", "
" ], "text/plain": [ " area population density\n", "california 423967 38332521 90.413926" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 슬라이싱이 열을 참조하도록 해보자.\n", "# 기대했던 것과는 다르게 마지막 행이 출력된다.\n", "data['area':'population'] " ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
areapopulationdensity
Illinois1499951288213585.883763
New York14129719651127139.076746
\n", "
" ], "text/plain": [ " area population density\n", "Illinois 149995 12882135 85.883763\n", "New York 141297 19651127 139.076746" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 슬라이싱은 숫자로 변경 가능\n", "data[1:3]" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Florida True\n", "Illinois False\n", "New York True\n", "Texas False\n", "california False\n", "Name: density, dtype: bool" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 마스킹 연산은 행 단위로 해석\n", "data.density > 100" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
areapopulationdensity
Florida17031219552860114.806121
New York14129719651127139.076746
\n", "
" ], "text/plain": [ " area population density\n", "Florida 170312 19552860 114.806121\n", "New York 141297 19651127 139.076746" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data[data.density > 100]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pandas에서 데이터 연산하기\n", "기본 산술 연산(덧셈, 뺄셈, 곱셈 등)과 복잡한 연산(삼각함수, 지수와 로그 함수 등) 모두에서 요소 단위의 연산을 빠르게 수행\n", " - 유니버설 함수 : 인덱스 보존\n", " - 유니버설 함수 : 인덱스 정렬\n", " - 유니버설 함수 : DataFrame과 Series간의 연산" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 유니버설 함수 : 인덱스 보존" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "- Pandas는 NumPy와 함께 작업하도록 설계됐기 때문에 NumPy의 유니버설 함수가 Pandas Series와 DataFrame 객체에 동작한다." ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 6\n", "1 3\n", "2 7\n", "3 4\n", "dtype: int64" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy as np\n", "import pandas as pd\n", "\n", "rng = np.random.RandomState(42)\n", "\n", "# 0~10까지 랜덤하게 4개의 수를 뽑아서 value로 만든다.\n", "ser = pd.Series(rng.randint(0, 10, 4))\n", "\n", "ser" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 403.428793\n", "1 20.085537\n", "2 1096.633158\n", "3 54.598150\n", "dtype: float64" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# index는 보존되고, value에만 지수 값이 적용 된다.\n", "np.exp(ser)" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ABCD
06926
17437
27254
\n", "
" ], "text/plain": [ " A B C D\n", "0 6 9 2 6\n", "1 7 4 3 7\n", "2 7 2 5 4" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 0~10까지 랜덤하게 수를 뽑아서 3 by 4 행렬을 만든다.\n", "df = pd.DataFrame(rng.randint(0, 10, (3 ,4)),\n", " columns=['A', 'B', 'C', 'D'])\n", "\n", "df" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ABCD
0-1.0000007.071068e-011.000000-1.000000e+00
1-0.7071071.224647e-160.707107-7.071068e-01
2-0.7071071.000000e+00-0.7071071.224647e-16
\n", "
" ], "text/plain": [ " A B C D\n", "0 -1.000000 7.071068e-01 1.000000 -1.000000e+00\n", "1 -0.707107 1.224647e-16 0.707107 -7.071068e-01\n", "2 -0.707107 1.000000e+00 -0.707107 1.224647e-16" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 마찬가지로 data frame 내의 value만 적용된다.\n", "np.sin(df * np.pi / 4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 유니버설 함수 : 인덱스 정렬\n", "- 두 개의 Series 또는 DataFrame 객체에 이항 연산을 적용하는 경우, Pandas는 연산을 수행하는 과정에서 인덱스를 정렬한다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **Series에서 인덱스 정렬**" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Alaska NaN\n", "California 90.413926\n", "New York NaN\n", "Texas 38.018740\n", "dtype: float64" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 두 개의 다른 데이터 소스를 결합해 미국 주에서 면적 기준 상위 세 개의 주와 인구 기준 상위 세 개의 주를 찾는다고 가정한다.\n", "area = pd.Series({'Alaska': 1723337, 'Texas': 695662,\n", " 'California': 423967}, name='area')\n", "\n", "population = pd.Series({'California': 38332521, 'Texas': 26448193,\n", " 'New York': 19651127}, name='population')\n", "\n", "# 결과 배열은 두 입력 배열의 인덱스의 합집합을 담고 있다.\n", "population / area" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 둘 중 하나라도 값이 없는 항목은 Pandas가 누락된 데이터를 표시하는 방식에 따라 NaN 즉, 숫자가 아님(Not a Number)으로 표시된다." ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 NaN\n", "1 5.0\n", "2 9.0\n", "3 NaN\n", "dtype: float64" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A = pd.Series([2, 4, 6], index=[0, 1, 2])\n", "B = pd.Series([1, 3, 5], index=[1, 2, 3])\n", "\n", "A + B" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- NaN 값 사용을 원치 않을 경우, 연산자 대신에 적절한 객체 메서드를 사용해 채우기 값을 수정할 수 있다." ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 2.0\n", "1 5.0\n", "2 9.0\n", "3 5.0\n", "dtype: float64" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 객체 메서드 add 사용, 비어있는 데이터에 0을 채워라.\n", "A.add(B, fill_value=0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> DataFrame에서 인덱스 정렬" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ab
0111
151
\n", "
" ], "text/plain": [ " a b\n", "0 1 11\n", "1 5 1" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A = pd.DataFrame(rng.randint(0, 20, (2, 2)), columns = list('ab'))\n", "A" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
bac
0409
1580
2926
\n", "
" ], "text/plain": [ " b a c\n", "0 4 0 9\n", "1 5 8 0\n", "2 9 2 6" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "B = pd.DataFrame(rng.randint(0, 10, (3, 3)), columns = list('bac'))\n", "B" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
abc
01.015.0NaN
113.06.0NaN
2NaNNaNNaN
\n", "
" ], "text/plain": [ " a b c\n", "0 1.0 15.0 NaN\n", "1 13.0 6.0 NaN\n", "2 NaN NaN NaN" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 없는 수의 경우 NaN이 채워진다.\n", "A + B" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
abc
01.015.0NaN
113.06.0NaN
2NaNNaNNaN
\n", "
" ], "text/plain": [ " a b c\n", "0 1.0 15.0 NaN\n", "1 13.0 6.0 NaN\n", "2 NaN NaN NaN" ] }, "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# add method를 사용하여 NaN을 채워 넣을 수 있다.\n", "A.add(B)" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 a 1\n", " b 11\n", "1 a 5\n", " b 1\n", "dtype: int64\n", "4.5\n" ] } ], "source": [ "print(A.stack())\n", "print(A.stack().mean())" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
abc
01.015.013.5
113.06.04.5
26.513.510.5
\n", "
" ], "text/plain": [ " a b c\n", "0 1.0 15.0 13.5\n", "1 13.0 6.0 4.5\n", "2 6.5 13.5 10.5" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fill = A.stack().mean()\n", "A.add(B, fill_value = fill)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 유니버설 함수 : DataFrame과 Series 간의 연산" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[3, 8, 2, 4],\n", " [2, 6, 4, 8],\n", " [6, 1, 3, 8]])" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A = rng.randint(10, size = (3, 4))\n", "A" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n" ] }, { "data": { "text/plain": [ "array([[ 0, 0, 0, 0],\n", " [-1, -2, 2, 4],\n", " [ 3, -7, 1, 4]])" ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "print(type(A))\n", "print(type(A[0]))\n", "\n", "A - A[0]" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
QRST
03824
12648
26138
\n", "
" ], "text/plain": [ " Q R S T\n", "0 3 8 2 4\n", "1 2 6 4 8\n", "2 6 1 3 8" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "Q 3\n", "R 8\n", "S 2\n", "T 4\n", "Name: 0, dtype: int64" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
QRST
00000
1-1-224
23-714
\n", "
" ], "text/plain": [ " Q R S T\n", "0 0 0 0 0\n", "1 -1 -2 2 4\n", "2 3 -7 1 4" ] }, "execution_count": 74, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.DataFrame(A, columns = list('QRST'))\n", "\n", "display(df)\n", "\n", "# df[0] : 에러 발생. 직접 해보시오. df.keys()를 쳐보자.\n", "display(df.iloc[0])\n", "\n", "# data frame에서 행으로 접근하기 위해서는 iloc을 사용한다.\n", "df - df.iloc[0]" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Q 3\n", "S 2\n", "Name: 0, dtype: int64" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
QRST
00.0NaN0.0NaN
1-1.0NaN2.0NaN
23.0NaN1.0NaN
\n", "
" ], "text/plain": [ " Q R S T\n", "0 0.0 NaN 0.0 NaN\n", "1 -1.0 NaN 2.0 NaN\n", "2 3.0 NaN 1.0 NaN" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# 0번 row를 가지고 오되, 스텝 사이즈가 2이다.\n", "halfrow = df.iloc[0, ::2]\n", "display(halfrow)\n", "\n", "display(df - halfrow)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 누락된 데이터 처리하기\n", "### Pandas에서 누락된 데이터" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **None : 파이썬의 누락된 데이터**\n", "> - None은 파이썬 객체이므로 모든 NumPy / Pandas 배열에서 사용할 수 없고 데이터 타입이 'object'인 배열에서만 사용할 수 있다. (즉 파이썬 객체의 배열)" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([1, None, 3, 4], dtype=object)" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "value1 = np.array([1, None, 3, 4])\n", "\n", "# value1의 dtype은 object이다.\n", "value1" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "unsupported operand type(s) for +: 'int' and 'NoneType'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# 배열에서 파이썬 객체를 사용한다는 것은 None 값을 가진 배열에서 `sum()` 이나 `min()` 같은 집계 연산을 하면 일반적으로 오류가 발생할 것이다.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mvalue1\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m/anaconda3/lib/python3.6/site-packages/numpy/core/_methods.py\u001b[0m in \u001b[0;36m_sum\u001b[0;34m(a, axis, dtype, out, keepdims)\u001b[0m\n\u001b[1;32m 30\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 31\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_sum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mout\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkeepdims\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 32\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mumr_sum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mout\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkeepdims\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 33\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 34\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_prod\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mout\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkeepdims\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for +: 'int' and 'NoneType'" ] } ], "source": [ "# 배열에서 파이썬 객체를 사용한다는 것은 None 값을 가진 배열에서 `sum()` 이나 `min()` 같은 집계 연산을 하면 일반적으로 오류가 발생할 것이다.\n", "value1.sum()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **NaN : 누락된 숫자 데이터**\n", "> - Not a Number" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dtype('float64')" ] }, "execution_count": 78, "metadata": {}, "output_type": "execute_result" } ], "source": [ "value2 = np.array([1, np.nan, 3, 4])\n", "value2.dtype" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "nan\n", "nan\n" ] } ], "source": [ "# NaN 덧셈\n", "print(1 + np.NaN)\n", "\n", "# NaN 곱셈\n", "print(0 * np.NaN)" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "nan\n", "nan\n" ] } ], "source": [ "# NaN이 존재 할 때, 연산에서 에러를 내지는 않지만 정확한 값을 출력하지 않는다.\n", "print(value2.sum())\n", "print(value2.min())" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "8.0\n", "1.0\n" ] } ], "source": [ "# 누락된 값을 무시하는 특별한 집계 연산\n", "print(np.nansum(value2))\n", "print(np.nanmin(value2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **Pandas에서 NaN과 None**" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 1.0\n", "1 NaN\n", "2 2.0\n", "3 NaN\n", "dtype: float64" ] }, "execution_count": 82, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Pandas는 nan과 none을 호환성 있게 처리하고, 적절한 경우 서로 변환할 수 있게 했다.\n", "pd.Series([1, np.nan, 2, None])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 널 값 연산하기" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **널 값 탐지**" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 False\n", "1 True\n", "2 False\n", "3 True\n", "dtype: bool" ] }, "execution_count": 83, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 부울 마스크를 반환\n", "data = pd.Series([1, np.nan, 'hello', None])\n", "data.isnull()" ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 True\n", "1 False\n", "2 True\n", "3 False\n", "dtype: bool" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "0 1\n", "2 hello\n", "dtype: object" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(data.notnull())\n", "\n", "# 부울 마스크는 Series나 DataFrame 인덱스로 직접 사용가능\n", "display(data[data.notnull()])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **널 값 제거하기**\n", "> - `dropna()` : nan 값 제거하기\n", "> - `fillna()` : nan 값 채우기" ] }, { "cell_type": "code", "execution_count": 85, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 1\n", "2 hello\n", "dtype: object" ] }, "execution_count": 85, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Series 의 경우\n", "data.dropna()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- DataFrame 에서는 단일 값을 지울 수는 없고 전체 행이나 전체 열을 삭제하는 것만 가능" ] }, { "cell_type": "code", "execution_count": 86, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
012
01.0NaN2
12.03.05
2NaN4.06
\n", "
" ], "text/plain": [ " 0 1 2\n", "0 1.0 NaN 2\n", "1 2.0 3.0 5\n", "2 NaN 4.0 6" ] }, "execution_count": 86, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# DataFrame 의 경우\n", "df = pd.DataFrame([[1, np.nan, 2], \n", " [2, 3, 5],\n", " [np.nan, 4, 6]])\n", "df" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
012
12.03.05
\n", "
" ], "text/plain": [ " 0 1 2\n", "1 2.0 3.0 5" ] }, "execution_count": 87, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.dropna()" ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
2
02
15
26
\n", "
" ], "text/plain": [ " 2\n", "0 2\n", "1 5\n", "2 6" ] }, "execution_count": 88, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 널 값을 포함하는 모든 열을 삭제하기 - data frame에서는 numpy와 달리 열을 삭제하기 위해서 axis = 1를 사용하였음에 주의하라.\n", "df.dropna(axis = 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 열 또는 행을 삭제할 때, 열과 행이 가지고 있는 널값의 갯수에 따라서 지울지 말지를 결정할 수 있다." ] }, { "cell_type": "code", "execution_count": 89, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
0123
01.0NaN2NaN
12.03.05NaN
2NaN4.06NaN
\n", "
" ], "text/plain": [ " 0 1 2 3\n", "0 1.0 NaN 2 NaN\n", "1 2.0 3.0 5 NaN\n", "2 NaN 4.0 6 NaN" ] }, "execution_count": 89, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# NaN으로만 이루어진 컬럼을 추가한다.\n", "df[3] = np.nan\n", "df" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
012
01.0NaN2
12.03.05
2NaN4.06
\n", "
" ], "text/plain": [ " 0 1 2\n", "0 1.0 NaN 2\n", "1 2.0 3.0 5\n", "2 NaN 4.0 6" ] }, "execution_count": 90, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# column의 모든 원소가 널 값일 때만 삭제\n", "df.dropna(axis = 1, how = 'all')" ] }, { "cell_type": "code", "execution_count": 91, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
0123
12.03.05NaN
\n", "
" ], "text/plain": [ " 0 1 2 3\n", "1 2.0 3.0 5 NaN" ] }, "execution_count": 91, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# row의 원소 중에서 널이 아닌 값이 최소 3개가 있어야 열을 삭제 하지 않음\n", "df.dropna(axis = 0, thresh = 3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **널 값 채우기**\n", "> - 널 값을 삭제하지 않고, 유효한 값으로 대체해야 할 때 `fillna()`메소드를 사용한다." ] }, { "cell_type": "code", "execution_count": 92, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 1.0\n", "b NaN\n", "c 2.0\n", "d NaN\n", "e 3.0\n", "dtype: float64" ] }, "execution_count": 92, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# series 일 때는 key를 설정하기 위해서 index, data frame 일 때는 key를 설정하기 위해서 columns\n", "data = pd.Series([1, np.nan, 2, None, 3], index = list('abcde'))\n", "data" ] }, { "cell_type": "code", "execution_count": 93, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 1.0\n", "b 0.0\n", "c 2.0\n", "d 0.0\n", "e 3.0\n", "dtype: float64" ] }, "execution_count": 93, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 단일 값 0으로 채우기\n", "data.fillna(0)" ] }, { "cell_type": "code", "execution_count": 94, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 1.0\n", "b 1.0\n", "c 2.0\n", "d 2.0\n", "e 3.0\n", "dtype: float64" ] }, "execution_count": 94, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 이전의 값(index - 1)으로 채우기\n", "data.fillna(method = 'ffill')" ] }, { "cell_type": "code", "execution_count": 95, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 1.0\n", "b 2.0\n", "c 2.0\n", "d 3.0\n", "e 3.0\n", "dtype: float64" ] }, "execution_count": 95, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 뒤의 값(index + 1)으로 채우기\n", "data.fillna(method = 'bfill')" ] }, { "cell_type": "code", "execution_count": 96, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
0123
01.0NaN2NaN
12.03.05NaN
2NaN4.06NaN
\n", "
" ], "text/plain": [ " 0 1 2 3\n", "0 1.0 NaN 2 NaN\n", "1 2.0 3.0 5 NaN\n", "2 NaN 4.0 6 NaN" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
0123
01.01.02.02.0
12.03.05.05.0
2NaN4.06.06.0
\n", "
" ], "text/plain": [ " 0 1 2 3\n", "0 1.0 1.0 2.0 2.0\n", "1 2.0 3.0 5.0 5.0\n", "2 NaN 4.0 6.0 6.0" ] }, "execution_count": 96, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# DafaFrame의 경우 축을 지정하여 채울 수 있다.\n", "display(df)\n", "\n", "df.fillna(method = 'ffill', axis = 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 계층적 인덱싱\n", "- Pandas는 기본적으로 3차원과 4차원 데이터를 처리할 수 있는 Panel과 Panel4D 개체를 제공한다.\n", "- 더 일반적으로 사용되는 패턴은 단일 인덱스 내에 여러 인덱스 레벨을 포함하는 **계층적 인덱싱**, **다중 인덱싱**이다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 데이터세트 결합 : Concat과 Append" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "두 개의 다른 데이터를 매우 간단하게 연결하는 것부터, 테이터 간 겹치는 부분을 제대로 처리하는 복잡한 데이터베이스 스타일을 조인하고 병합하는 것까지 다양하게 사용될 수 있다. Series, DataFrame은 이 유형의 연산을 염두에 두고 만들어진 것이다.\n", "- 데이터 랭글링(Data Wrangling), 데이터 먼징(Data Munging) : 원자료(raw data)를 또 다른 형태로 전환하거나 매핑하는 과정" ] }, { "cell_type": "code", "execution_count": 97, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ABC
0A0B0C0
1A1B1C1
2A2B2C2
\n", "
" ], "text/plain": [ " A B C\n", "0 A0 B0 C0\n", "1 A1 B1 C1\n", "2 A2 B2 C2" ] }, "execution_count": 97, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "\n", "# 사용할 메소드를 미리 만들자.\n", "def make_df(cols, rows):\n", " \"\"\"빠르게 DataFrame을 생성\"\"\"\n", " data = {c : [str(c) + str(i) for i in rows] for c in cols}\n", " return pd.DataFrame(data, rows)\n", " \n", "# 예제\n", "make_df('ABC', range(3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### pd.concat을 이용한 간단한 연결\n", "> **Series 객체를 간단하게 연결할 때 사용**" ] }, { "cell_type": "code", "execution_count": 98, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1 A\n", "2 B\n", "3 C\n", "dtype: object" ] }, "execution_count": 98, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ser1 = pd.Series(['A', 'B', 'C'], index = [1, 2, 3])\n", "ser1" ] }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4 D\n", "5 E\n", "6 F\n", "dtype: object" ] }, "execution_count": 99, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ser2 = pd.Series(['D', 'E', 'F'], index = [4, 5, 6])\n", "ser2" ] }, { "cell_type": "code", "execution_count": 100, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 A\n", "2 B\n", "3 C\n", "4 D\n", "5 E\n", "6 F\n", "dtype: object\n" ] } ], "source": [ "# Concat의 기본값은 axis=0이다. 즉 row에 concat 된다.\n", "print(pd.concat([ser1, ser2]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **DataFrame 객체를 간단하게 연결할 때 사용 1**" ] }, { "cell_type": "code", "execution_count": 101, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AB
1A1B1
2A2B2
\n", "
" ], "text/plain": [ " A B\n", "1 A1 B1\n", "2 A2 B2" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AB
3A3B3
4A4B4
\n", "
" ], "text/plain": [ " A B\n", "3 A3 B3\n", "4 A4 B4" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AB
1A1B1
2A2B2
3A3B3
4A4B4
\n", "
" ], "text/plain": [ " A B\n", "1 A1 B1\n", "2 A2 B2\n", "3 A3 B3\n", "4 A4 B4" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "df1 = make_df('AB', [1, 2])\n", "df2 = make_df('AB', [3, 4])\n", "\n", "display(df1)\n", "display(df2)\n", "\n", "# 기본적으로 row 아래로 연결된다.\n", "display(pd.concat([df1, df2]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **DataFrame 객체를 간단하게 연결할 때 사용 2**" ] }, { "cell_type": "code", "execution_count": 102, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AB
0A0B0
1A1B1
\n", "
" ], "text/plain": [ " A B\n", "0 A0 B0\n", "1 A1 B1" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CD
0C0D0
1C1D1
\n", "
" ], "text/plain": [ " C D\n", "0 C0 D0\n", "1 C1 D1" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ABCD
0A0B0NaNNaN
1A1B1NaNNaN
0NaNNaNC0D0
1NaNNaNC1D1
\n", "
" ], "text/plain": [ " A B C D\n", "0 A0 B0 NaN NaN\n", "1 A1 B1 NaN NaN\n", "0 NaN NaN C0 D0\n", "1 NaN NaN C1 D1" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ABCD
0A0B0C0D0
1A1B1C1D1
\n", "
" ], "text/plain": [ " A B C D\n", "0 A0 B0 C0 D0\n", "1 A1 B1 C1 D1" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "df3 = make_df('AB', [0, 1])\n", "df4 = make_df('CD', [0, 1])\n", "\n", "display(df3)\n", "display(df4)\n", "\n", "# row 아래로 붙일 때\n", "display(pd.concat([df3, df4], axis = 0))\n", "\n", "# column 뒤에 붙일 때\n", "display(pd.concat([df3, df4], axis = 1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **인덱스 복제**\n", "> - `np.concatenate`, `pd.concat`의 중요한 차이는 Pandas에서의 연결은 그 결과가 복제된 인덱스를 가지더라도 인덱스를 유지하는 것" ] }, { "cell_type": "code", "execution_count": 103, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AB
0A0B0
1A1B1
\n", "
" ], "text/plain": [ " A B\n", "0 A0 B0\n", "1 A1 B1" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AB
0A2B2
1A3B3
\n", "
" ], "text/plain": [ " A B\n", "0 A2 B2\n", "1 A3 B3" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "Int64Index([0, 1], dtype='int64')" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "Int64Index([0, 1], dtype='int64')" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "x = make_df('AB', [0, 1])\n", "y = make_df('AB', [2, 3])\n", "\n", "# 복제 인덱스 생성\n", "y.index = x.index\n", "\n", "display(x)\n", "display(y)\n", "\n", "display(x.index)\n", "display(y.index)" ] }, { "cell_type": "code", "execution_count": 104, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AB
0A0B0
1A1B1
0A2B2
1A3B3
\n", "
" ], "text/plain": [ " A B\n", "0 A0 B0\n", "1 A1 B1\n", "0 A2 B2\n", "1 A3 B3" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# 인덱스가 복제되어서 겹쳐진다.\n", "concated_df = pd.concat([x, y])\n", "display(concated_df)" ] }, { "cell_type": "code", "execution_count": 105, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "A A0\n", "B B0\n", "Name: 0, dtype: object" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "A A2\n", "B B2\n", "Name: 0, dtype: object" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# 기존의 인덱스가 유지된다.\n", "# Index를 겹쳐지지 않게 처리할 수 있는 방법은?\n", "display(concated_df.iloc[0])\n", "display(concated_df.iloc[2])" ] }, { "cell_type": "code", "execution_count": 106, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ValueError: Indexes have overlapping values: [0, 1]\n" ] } ], "source": [ "\"\"\"처리 방법 1 : 반복을 에러로 잡아낸다.\"\"\"\n", "\n", "try:\n", " pd.concat([x, y], verify_integrity = True)\n", "except ValueError as e:\n", " print(\"ValueError:\", e)" ] }, { "cell_type": "code", "execution_count": 107, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AB
0A0B0
1A1B1
\n", "
" ], "text/plain": [ " A B\n", "0 A0 B0\n", "1 A1 B1" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AB
0A2B2
1A3B3
\n", "
" ], "text/plain": [ " A B\n", "0 A2 B2\n", "1 A3 B3" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AB
0A0B0
1A1B1
2A2B2
3A3B3
\n", "
" ], "text/plain": [ " A B\n", "0 A0 B0\n", "1 A1 B1\n", "2 A2 B2\n", "3 A3 B3" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "\"\"\"처리 방법 2 : 인덱스를 무시한다.\"\"\"\n", "display(x)\n", "display(y)\n", "\n", "display(pd.concat([x, y], ignore_index = True))" ] }, { "cell_type": "code", "execution_count": 108, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AB
0A0B0
1A1B1
\n", "
" ], "text/plain": [ " A B\n", "0 A0 B0\n", "1 A1 B1" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AB
0A2B2
1A3B3
\n", "
" ], "text/plain": [ " A B\n", "0 A2 B2\n", "1 A3 B3" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AB
a0A0B0
1A1B1
b0A2B2
1A3B3
\n", "
" ], "text/plain": [ " A B\n", "a 0 A0 B0\n", " 1 A1 B1\n", "b 0 A2 B2\n", " 1 A3 B3" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "\"\"\"처리 방법 3 : 다중 인덱스 키를 추가한다.\"\"\"\n", "display(x)\n", "display(y)\n", "\n", "display(pd.concat([x, y], keys = ['a', 'b']))" ] }, { "cell_type": "code", "execution_count": 109, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AB
a0A0B0
1A1B1
b0A2B2
1A3B3
\n", "
" ], "text/plain": [ " A B\n", "a 0 A0 B0\n", " 1 A1 B1\n", "b 0 A2 B2\n", " 1 A3 B3" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "\"\"\"새로운 키가 row에 형성된다.\"\"\"\n", "new_row_key = pd.concat([x, y], axis=0, keys = ['a', 'b'])\n", "display(new_row_key)" ] }, { "cell_type": "code", "execution_count": 110, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'A0'" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "A A0\n", "B B0\n", "Name: (a, 0), dtype: object" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "'B3'" ] }, "execution_count": 110, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 다중 인덱스를 이용하여 하나의 원소에 접근하려면 tuple 형태로 접근해야 한다.\n", "display(new_row_key.loc[(\"a\", 0), \"A\"])\n", "\n", "# 다중 인덱스를 이용하여 row에 접근하려면 아래와 같이 접근해야 한다.\n", "display(new_row_key.loc[(\"a\", 0)])\n", "\n", "# 다중 인덱스와 iloc을 함께 사용하여 원소 및 row에 접근할 수는 없다. \n", "new_row_key.iloc[3, 1]" ] }, { "cell_type": "code", "execution_count": 111, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ab
ABAB
0A0B0A2B2
1A1B1A3B3
\n", "
" ], "text/plain": [ " a b \n", " A B A B\n", "0 A0 B0 A2 B2\n", "1 A1 B1 A3 B3" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "\"\"\"새로운 키가 column에 형성된다.\"\"\"\n", "new_col_key = pd.concat([x, y], axis=1, keys = ['a', 'b'])\n", "display(new_col_key)" ] }, { "cell_type": "code", "execution_count": 112, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'A0'" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "0 A0\n", "1 A1\n", "Name: A, dtype: object" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# 다중 인덱스를 이용하여 하나의 원소에 접근하는 법은 위와 비슷하다.\n", "display(new_col_key.loc[0, ('a', 'A')])\n", "\n", "# 다중 인덱스를 이용하여 column에 접근\n", "display(new_col_key['a']['A'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **Concat 및 Join을 이용한 연결**" ] }, { "cell_type": "code", "execution_count": 113, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ABC
1A1B1C1
2A2B2C2
\n", "
" ], "text/plain": [ " A B C\n", "1 A1 B1 C1\n", "2 A2 B2 C2" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
BCD
1B1C1D1
2B2C2D2
\n", "
" ], "text/plain": [ " B C D\n", "1 B1 C1 D1\n", "2 B2 C2 D2" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "\"\"\"컬럼의 이름이 같은 것끼리 조인된다. defualt는 outer 조인이다.\"\"\"\n", "\n", "df5 = make_df('ABC', [1, 2])\n", "df6 = make_df('BCD', [1, 2])\n", "\n", "display(df5)\n", "display(df6)" ] }, { "cell_type": "code", "execution_count": 114, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ABCD
1A1B1C1NaN
2A2B2C2NaN
1NaNB1C1D1
2NaNB2C2D2
\n", "
" ], "text/plain": [ " A B C D\n", "1 A1 B1 C1 NaN\n", "2 A2 B2 C2 NaN\n", "1 NaN B1 C1 D1\n", "2 NaN B2 C2 D2" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# outer 조인이기 때문에 없는 값은 NaN으로 채워진다.\n", "display(pd.concat([df5, df6]))" ] }, { "cell_type": "code", "execution_count": 115, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
BC
1B1C1
2B2C2
1B1C1
2B2C2
\n", "
" ], "text/plain": [ " B C\n", "1 B1 C1\n", "2 B2 C2\n", "1 B1 C1\n", "2 B2 C2" ] }, "execution_count": 115, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"inner 조인 사용하면 교집합으로 변경된다.\"\"\"\n", "\n", "pd.concat([df5, df6], join='inner')" ] }, { "cell_type": "code", "execution_count": 116, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ABC
1A1B1C1
2A2B2C2
1NaNB1C1
2NaNB2C2
\n", "
" ], "text/plain": [ " A B C\n", "1 A1 B1 C1\n", "2 A2 B2 C2\n", "1 NaN B1 C1\n", "2 NaN B2 C2" ] }, "execution_count": 116, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"남기고 싶은 열을 지정할 수 있다.\"\"\"\n", "\n", "# A, B, C 열만 남기고 싶은 경우.\n", "pd.concat([df5, df6], join_axes=[df5.columns])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **append 메서드**\n", "> - 원래의 객체를 변경하지 않고, 결합된 데이터를 가지는 새로운 객체를 만든다.\n", "> - 새 인덱스와 데이터 버퍼를 생성하기 때문에 매우 효율적인 방식이라고 보기는 어렵다." ] }, { "cell_type": "code", "execution_count": 117, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AB
1A1B1
2A2B2
\n", "
" ], "text/plain": [ " A B\n", "1 A1 B1\n", "2 A2 B2" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AB
3A3B3
4A4B4
\n", "
" ], "text/plain": [ " A B\n", "3 A3 B3\n", "4 A4 B4" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(df1)\n", "display(df2)" ] }, { "cell_type": "code", "execution_count": 118, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AB
1A1B1
2A2B2
3A3B3
4A4B4
\n", "
" ], "text/plain": [ " A B\n", "1 A1 B1\n", "2 A2 B2\n", "3 A3 B3\n", "4 A4 B4" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(df1.append(df2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 데이터세트 결합하기 : 병합과 조인\n", " - Pandas가 제공하는 기본 기능의 하나는 고성능 인메모리 조인과 병합 연산이다.\n", " - `pd.merge` 함수이다." ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "### 관계 대수\n", "- 관계 데이터(Relation data)를 조작하는 규칙의 정형 집합이자 대부분의 데이터베이스에서 사용할 수 있는 연산의 개념적 기반을 형성하는 관계 대수(Relation algebra)의 하위 집합에 해당하는 행위가 구현됨\n", "- `pd.merge()` 함수는 일대일, 다대일, 다대다 조인 같은 여러 가지 조인 유형을 구현한다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **일대일 조인**" ] }, { "cell_type": "code", "execution_count": 119, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
employeegroup
0BobAccounting
1JakeEngineering
2LisaEngineering
3SueHR
\n", "
" ], "text/plain": [ " employee group\n", "0 Bob Accounting\n", "1 Jake Engineering\n", "2 Lisa Engineering\n", "3 Sue HR" ] }, "execution_count": 119, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 회사의 직원 몇 명에 대한 정보를 포함하는 두 개의 DataFrame을 생각해보자.\n", "import pandas as pd\n", "\n", "df1 = pd.DataFrame({'employee': ['Bob', 'Jake', 'Lisa', 'Sue'],\n", " 'group': ['Accounting', 'Engineering', 'Engineering', 'HR']})\n", "df1" ] }, { "cell_type": "code", "execution_count": 120, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
employeehire_date
0Lisa2004
1Bob2008
2Jake2012
3Sue2014
\n", "
" ], "text/plain": [ " employee hire_date\n", "0 Lisa 2004\n", "1 Bob 2008\n", "2 Jake 2012\n", "3 Sue 2014" ] }, "execution_count": 120, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df2 = pd.DataFrame({'employee': ['Lisa', 'Bob', 'Jake', 'Sue'],\n", " 'hire_date': [2004, 2008, 2012, 2014]})\n", "df2" ] }, { "cell_type": "code", "execution_count": 121, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
employeegrouphire_date
0BobAccounting2008
1JakeEngineering2012
2LisaEngineering2004
3SueHR2014
\n", "
" ], "text/plain": [ " employee group hire_date\n", "0 Bob Accounting 2008\n", "1 Jake Engineering 2012\n", "2 Lisa Engineering 2004\n", "3 Sue HR 2014" ] }, "execution_count": 121, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 이 정보를 하나의 DataFrame으로 결합하고 싶다.\n", "df3 = pd.merge(df1, df2)\n", "df3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`pd.merge()` 함수는 DataFrame이 employee 열을 가지고 있다는 것을 알고 자동으로 이 열을 **키**로 사용해 조인한다. 이 때 각 열의 항목 순서가 반드시 유지되는 것은 아니다. 각 열의 항목 순서를 `pd.merge()` 함수가 정확하게 맞추어 연산한다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **다대일(many-to-one) 조인**\n", "- 두 개의 키 열 중 하나가 중복된 항목을 포함하는 경우의 조인을 의미한다." ] }, { "cell_type": "code", "execution_count": 122, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
employeegrouphire_date
0BobAccounting2008
1JakeEngineering2012
2LisaEngineering2004
3SueHR2014
\n", "
" ], "text/plain": [ " employee group hire_date\n", "0 Bob Accounting 2008\n", "1 Jake Engineering 2012\n", "2 Lisa Engineering 2004\n", "3 Sue HR 2014" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
groupsupervisor
0AccountingCarly
1EngineeringGuido
2HRSteve
\n", "
" ], "text/plain": [ " group supervisor\n", "0 Accounting Carly\n", "1 Engineering Guido\n", "2 HR Steve" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "df4 = pd.DataFrame({'group': ['Accounting', 'Engineering', 'HR'],\n", " 'supervisor': ['Carly', 'Guido', 'Steve']})\n", "\n", "display(df3)\n", "display(df4)" ] }, { "cell_type": "code", "execution_count": 123, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
employeegrouphire_datesupervisor
0BobAccounting2008Carly
1JakeEngineering2012Guido
2LisaEngineering2004Guido
3SueHR2014Steve
\n", "
" ], "text/plain": [ " employee group hire_date supervisor\n", "0 Bob Accounting 2008 Carly\n", "1 Jake Engineering 2012 Guido\n", "2 Lisa Engineering 2004 Guido\n", "3 Sue HR 2014 Steve" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(pd.merge(df3, df4))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **다대다(Many-to-many) 조인**\n", "- 왼쪽과 오른쪽 배열의 키 열에 모두 중복 항목이 존재하면 결과는 다대다 병합이 된다." ] }, { "cell_type": "code", "execution_count": 124, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
employeegroup
0BobAccounting
1JakeEngineering
2LisaEngineering
3SueHR
\n", "
" ], "text/plain": [ " employee group\n", "0 Bob Accounting\n", "1 Jake Engineering\n", "2 Lisa Engineering\n", "3 Sue HR" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
grouphire_date
0Accountingmath
1Accountingspreadsheets
2Engineeringcoding
3Engineeringlinux
4HRspreadsheets
5HRorganization
\n", "
" ], "text/plain": [ " group hire_date\n", "0 Accounting math\n", "1 Accounting spreadsheets\n", "2 Engineering coding\n", "3 Engineering linux\n", "4 HR spreadsheets\n", "5 HR organization" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "df5 = pd.DataFrame({'group': ['Accounting', 'Accounting',\n", " 'Engineering', 'Engineering',\n", " 'HR', 'HR'],\n", " 'hire_date': ['math', 'spreadsheets', \n", " 'coding', 'linux', \n", " 'spreadsheets', 'organization']})\n", "display(df1)\n", "display(df5)" ] }, { "cell_type": "code", "execution_count": 125, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
employeegrouphire_date
0BobAccountingmath
1BobAccountingspreadsheets
2JakeEngineeringcoding
3JakeEngineeringlinux
4LisaEngineeringcoding
5LisaEngineeringlinux
6SueHRspreadsheets
7SueHRorganization
\n", "
" ], "text/plain": [ " employee group hire_date\n", "0 Bob Accounting math\n", "1 Bob Accounting spreadsheets\n", "2 Jake Engineering coding\n", "3 Jake Engineering linux\n", "4 Lisa Engineering coding\n", "5 Lisa Engineering linux\n", "6 Sue HR spreadsheets\n", "7 Sue HR organization" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(pd.merge(df1, df5))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 병합 키 지정\n", "- `pd.merge()`는 두 개의 입력값 사이에 일치하는 하나 이상의 열 이름을 찾아 그것을 키로 사용\n", "- 열 이름이 잘 일치하는 경우는 흔하지 않으며, pd.merge()가 이 문제를 처리하기 위한 다양한 옵션을 제공" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **on 키워드**\n", "- 가장 간단한 방볍은 열 이름이나 열이름의 리스트를 취하는 on 키워드를 사용해 키 열의 이름을 명시적으로 지정하는 것이다." ] }, { "cell_type": "code", "execution_count": 126, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
employeegroup
0BobAccounting
1JakeEngineering
2LisaEngineering
3SueHR
\n", "
" ], "text/plain": [ " employee group\n", "0 Bob Accounting\n", "1 Jake Engineering\n", "2 Lisa Engineering\n", "3 Sue HR" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
employeehire_date
0Lisa2004
1Bob2008
2Jake2012
3Sue2014
\n", "
" ], "text/plain": [ " employee hire_date\n", "0 Lisa 2004\n", "1 Bob 2008\n", "2 Jake 2012\n", "3 Sue 2014" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(df1)\n", "display(df2)" ] }, { "cell_type": "code", "execution_count": 127, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
employeegrouphire_date
0BobAccounting2008
1JakeEngineering2012
2LisaEngineering2004
3SueHR2014
\n", "
" ], "text/plain": [ " employee group hire_date\n", "0 Bob Accounting 2008\n", "1 Jake Engineering 2012\n", "2 Lisa Engineering 2004\n", "3 Sue HR 2014" ] }, "execution_count": 127, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.merge(df1, df2, on='employee')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "이 옵션은 왼쪽과 오른쪽 DataFrame이 모두 지정된 열 이름을 가진 경우에만 동작한다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **left_on과 right_on 키워드**\n", "- 다른 열 이름을 가진 두 데이터 세트를 병합하고 싶을 때 사용한다." ] }, { "cell_type": "code", "execution_count": 128, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
employeegroup
0BobAccounting
1JakeEngineering
2LisaEngineering
3SueHR
\n", "
" ], "text/plain": [ " employee group\n", "0 Bob Accounting\n", "1 Jake Engineering\n", "2 Lisa Engineering\n", "3 Sue HR" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
namesalary
0Bob70000
1Jake80000
2Lisa120000
3Sue90000
\n", "
" ], "text/plain": [ " name salary\n", "0 Bob 70000\n", "1 Jake 80000\n", "2 Lisa 120000\n", "3 Sue 90000" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "df3 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'],\n", " 'salary': [70000, 80000, 120000, 90000]})\n", "\n", "display(df1)\n", "display(df3)" ] }, { "cell_type": "code", "execution_count": 129, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
employeegroupnamesalary
0BobAccountingBob70000
1JakeEngineeringJake80000
2LisaEngineeringLisa120000
3SueHRSue90000
\n", "
" ], "text/plain": [ " employee group name salary\n", "0 Bob Accounting Bob 70000\n", "1 Jake Engineering Jake 80000\n", "2 Lisa Engineering Lisa 120000\n", "3 Sue HR Sue 90000" ] }, "execution_count": 129, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.merge(df1, df3, left_on=\"employee\", right_on=\"name\")" ] }, { "cell_type": "code", "execution_count": 130, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
employeegroupsalary
0BobAccounting70000
1JakeEngineering80000
2LisaEngineering120000
3SueHR90000
\n", "
" ], "text/plain": [ " employee group salary\n", "0 Bob Accounting 70000\n", "1 Jake Engineering 80000\n", "2 Lisa Engineering 120000\n", "3 Sue HR 90000" ] }, "execution_count": 130, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 중복된 열은 삭제하도록 한다.\n", "pd.merge(df1, df3, left_on=\"employee\", right_on=\"name\").drop(\"name\", axis = 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **left_index와 right_index 키워드**\n", "- 열을 병합하는 대신 인덱스로 병합해야 하는 경우도 있다." ] }, { "cell_type": "code", "execution_count": 131, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
employeegroup
0BobAccounting
1JakeEngineering
2LisaEngineering
3SueHR
\n", "
" ], "text/plain": [ " employee group\n", "0 Bob Accounting\n", "1 Jake Engineering\n", "2 Lisa Engineering\n", "3 Sue HR" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
employeehire_date
0Lisa2004
1Bob2008
2Jake2012
3Sue2014
\n", "
" ], "text/plain": [ " employee hire_date\n", "0 Lisa 2004\n", "1 Bob 2008\n", "2 Jake 2012\n", "3 Sue 2014" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# 먼저 df1, df2를 보자.\n", "display(df1)\n", "display(df2)" ] }, { "cell_type": "code", "execution_count": 132, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
group
employee
BobAccounting
JakeEngineering
LisaEngineering
SueHR
\n", "
" ], "text/plain": [ " group\n", "employee \n", "Bob Accounting\n", "Jake Engineering\n", "Lisa Engineering\n", "Sue HR" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
hire_date
employee
Lisa2004
Bob2008
Jake2012
Sue2014
\n", "
" ], "text/plain": [ " hire_date\n", "employee \n", "Lisa 2004\n", "Bob 2008\n", "Jake 2012\n", "Sue 2014" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# 컬럼 이름이었던 것을 인덱스를 설정\n", "df1a = df1.set_index('employee')\n", "df2a = df2.set_index('employee')\n", "\n", "display(df1a)\n", "display(df2a)" ] }, { "cell_type": "code", "execution_count": 133, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
grouphire_date
employee
BobAccounting2008
JakeEngineering2012
LisaEngineering2004
SueHR2014
\n", "
" ], "text/plain": [ " group hire_date\n", "employee \n", "Bob Accounting 2008\n", "Jake Engineering 2012\n", "Lisa Engineering 2004\n", "Sue HR 2014" ] }, "execution_count": 133, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 이 때는 left_index나 right_index를 지정하여 조인\n", "pd.merge(df1a, df2a, left_index=True, right_index=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 편의를 위해 DataFrame은 기본적으로 인덱스 기반으로 조인하는 병합을 수행하는 `join()` 메서드를 구현한다." ] }, { "cell_type": "code", "execution_count": 134, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
grouphire_date
employee
BobAccounting2008
JakeEngineering2012
LisaEngineering2004
SueHR2014
\n", "
" ], "text/plain": [ " group hire_date\n", "employee \n", "Bob Accounting 2008\n", "Jake Engineering 2012\n", "Lisa Engineering 2004\n", "Sue HR 2014" ] }, "execution_count": 134, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df1a.join(df2a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "인덱스와 열을 섞고자 한다면 `left_index`를 `right_on`과 결합하거나 `left_on`을 `right_index`와 결합해 원하는 결과를 얻을 수 있다." ] }, { "cell_type": "code", "execution_count": 135, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
group
employee
BobAccounting
JakeEngineering
LisaEngineering
SueHR
\n", "
" ], "text/plain": [ " group\n", "employee \n", "Bob Accounting\n", "Jake Engineering\n", "Lisa Engineering\n", "Sue HR" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
namesalary
0Bob70000
1Jake80000
2Lisa120000
3Sue90000
\n", "
" ], "text/plain": [ " name salary\n", "0 Bob 70000\n", "1 Jake 80000\n", "2 Lisa 120000\n", "3 Sue 90000" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(df1a)\n", "display(df3)" ] }, { "cell_type": "code", "execution_count": 136, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
groupnamesalary
0AccountingBob70000
1EngineeringJake80000
2EngineeringLisa120000
3HRSue90000
\n", "
" ], "text/plain": [ " group name salary\n", "0 Accounting Bob 70000\n", "1 Engineering Jake 80000\n", "2 Engineering Lisa 120000\n", "3 HR Sue 90000" ] }, "execution_count": 136, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.merge(df1a, df3, left_index=True, right_on=\"name\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " ### 조인을 위한 집합 연산 지정하기\n", " - inner join\n", " - outer join\n", " - left join\n", " - right join" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **inner join**" ] }, { "cell_type": "code", "execution_count": 137, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
namefood
0Peterfish
1Paulbeans
2Marybread
\n", "
" ], "text/plain": [ " name food\n", "0 Peter fish\n", "1 Paul beans\n", "2 Mary bread" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
namedrink
0Marywine
1Josephbeer
\n", "
" ], "text/plain": [ " name drink\n", "0 Mary wine\n", "1 Joseph beer" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "df6 = pd.DataFrame({'name': ['Peter', 'Paul', 'Mary'],\n", " 'food': ['fish', 'beans', 'bread']},\n", " columns=['name', 'food'])\n", "\n", "df7 = pd.DataFrame({'name': ['Mary', 'Joseph'],\n", " 'drink': ['wine', 'beer']},\n", " columns=['name', 'drink'])\n", "\n", "display(df6)\n", "display(df7)" ] }, { "cell_type": "code", "execution_count": 138, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
namefooddrink
0Marybreadwine
\n", "
" ], "text/plain": [ " name food drink\n", "0 Mary bread wine" ] }, "execution_count": 138, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 기본적으로 결과에는 입력값의 두 집합에 대한 교집합이 들어간다.\n", "pd.merge(df6, df7)" ] }, { "cell_type": "code", "execution_count": 139, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
namefooddrink
0Marybreadwine
\n", "
" ], "text/plain": [ " name food drink\n", "0 Mary bread wine" ] }, "execution_count": 139, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 명시적으로는 다음과 같이 한다.\n", "pd.merge(df6, df7, how='inner')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **outer join**" ] }, { "cell_type": "code", "execution_count": 140, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
namefooddrink
0PeterfishNaN
1PaulbeansNaN
2Marybreadwine
3JosephNaNbeer
\n", "
" ], "text/plain": [ " name food drink\n", "0 Peter fish NaN\n", "1 Paul beans NaN\n", "2 Mary bread wine\n", "3 Joseph NaN beer" ] }, "execution_count": 140, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.merge(df6, df7, how='outer')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **left join**\n", "- 왼쪽 항목을 기준으로 한다." ] }, { "cell_type": "code", "execution_count": 141, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
namefooddrink
0PeterfishNaN
1PaulbeansNaN
2Marybreadwine
\n", "
" ], "text/plain": [ " name food drink\n", "0 Peter fish NaN\n", "1 Paul beans NaN\n", "2 Mary bread wine" ] }, "execution_count": 141, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.merge(df6, df7, how='left')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **right join**\n", "- 오른쪽 항목을 기준으로 한다." ] }, { "cell_type": "code", "execution_count": 142, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
namefooddrink
0Marybreadwine
1JosephNaNbeer
\n", "
" ], "text/plain": [ " name food drink\n", "0 Mary bread wine\n", "1 Joseph NaN beer" ] }, "execution_count": 142, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.merge(df6, df7, how='right')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 열 이름이 겹치는 경우 : Suffixes 키워드\n", "- 충돌하는 이름을 가진 경우를 살펴보자." ] }, { "cell_type": "code", "execution_count": 143, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
namerank
0Bob1
1Jake2
2Lisa3
3Sue4
\n", "
" ], "text/plain": [ " name rank\n", "0 Bob 1\n", "1 Jake 2\n", "2 Lisa 3\n", "3 Sue 4" ] }, "execution_count": 143, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df8 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'],\n", " 'rank': [1, 2, 3, 4]})\n", "df8" ] }, { "cell_type": "code", "execution_count": 144, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
namerank
0Bob3
1Jake1
2Lisa4
3Sue2
\n", "
" ], "text/plain": [ " name rank\n", "0 Bob 3\n", "1 Jake 1\n", "2 Lisa 4\n", "3 Sue 2" ] }, "execution_count": 144, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df9 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'],\n", " 'rank': [3, 1, 4, 2]})\n", "df9" ] }, { "cell_type": "code", "execution_count": 145, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
namerank_xrank_y
0Bob13
1Jake21
2Lisa34
3Sue42
\n", "
" ], "text/plain": [ " name rank_x rank_y\n", "0 Bob 1 3\n", "1 Jake 2 1\n", "2 Lisa 3 4\n", "3 Sue 4 2" ] }, "execution_count": 145, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# name을 key로 하면 rank가 겹쳐진다. 이 경우는 자동으로 이름이 변경된다.\n", "pd.merge(df8, df9, on='name')" ] }, { "cell_type": "code", "execution_count": 146, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
namerank_Lrank_R
0Bob13
1Jake21
2Lisa34
3Sue42
\n", "
" ], "text/plain": [ " name rank_L rank_R\n", "0 Bob 1 3\n", "1 Jake 2 1\n", "2 Lisa 3 4\n", "3 Sue 4 2" ] }, "execution_count": 146, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# suffixes 키워드를 사용해서 접미사를 별도로 줄 수 있다.\n", "pd.merge(df8, df9, on='name', suffixes=[\"_L\", \"_R\"])" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.6" } }, "nbformat": 4, "nbformat_minor": 1 }