'''
원본 소스코드에 대한 설명:
### 작성 : [PinkWink](http://pinkwink.kr)
* 강남3구의 주민들이 자신들이 거주하는 구의 체감 안전도를 높게 생각한다는 기사를 확인해 보도록 한다
* 기사 원문 http://news1.kr/articles/?1911504
* 작성 : PinkWink http://pinkwink.kr
* Matplotlib의 heatmap 등을 그릴때 cmap의 디폴트 설정이 변경되어 heatmap 등에서 cmap을 적용할 때 옵션을 잡아주어야 교재와 동일한 효과가 나타난다. (소스코드에 모두 반영됨)
* Folium이 0.4.0으로 판올림 되면서 choropleth 명령에서 geo_str 옵션명이 geo_data 옵션명으로 변경됨. (소스코드에 모두 반영)
* Folium이 0.4.0으로 판올림 되면서 circle marker 적용할때, fill=True 옵션을 반듯이 사용해야 함. (소스코드에 모두 반영)
'''
'\n원본 소스코드에 대한 설명:\n\n### 작성 : [PinkWink](http://pinkwink.kr) \n\n* 강남3구의 주민들이 자신들이 거주하는 구의 체감 안전도를 높게 생각한다는 기사를 확인해 보도록 한다\n* 기사 원문 http://news1.kr/articles/?1911504\n* 작성 : PinkWink http://pinkwink.kr\n\n* Matplotlib의 heatmap 등을 그릴때 cmap의 디폴트 설정이 변경되어 heatmap 등에서 cmap을 적용할 때 옵션을 잡아주어야 교재와 동일한 효과가 나타난다. (소스코드에 모두 반영됨)\n* Folium이 0.4.0으로 판올림 되면서 choropleth 명령에서 geo_str 옵션명이 geo_data 옵션명으로 변경됨. (소스코드에 모두 반영)\n* Folium이 0.4.0으로 판올림 되면서 circle marker 적용할때, fill=True 옵션을 반듯이 사용해야 함. (소스코드에 모두 반영)\n\n'
강남 3구는 안전한가?
9월 11일 수요일 강의 발표에 대한 부분
교재에 없는 내용이 포함되어 있습니다.
원본 소스코드에 없는 코드와 주석이 포함되어 있습니다.
!!!!주석에 대하여!!!!
중복된 내용은 코드 주석을 스킵 하였습니다.
데이터 정리하기
필요한 모듈을 import한다.
import numpy as np
import pandas as pd
'''
cp949, utf-8, iso8859-1, euc-kr
https://docs.python.org/3/library/codecs.html#standard-encodings
여기서 찾아보면 됩니다.
'''
받은 데이터(csv) 파일을 읽는다, 콤마(,)로 천단위가 구분되어 있고, 한글 엔코딩은 euc-kr이다
교재에서 접근하는 방식으로 데이터를 얻으로 가면 교재 집필하던 때와 데이터의 형식이 변경되어 있다.
지금은 데이터를 얻는 것이 실제 데이터라는 것에 대한 증명일 뿐이므로, 해당 데이터를 Github에서 배포하는 데이터를 다운받는 것으로 한다.
# 파이썬 document(공식문서)에는 인코딩 방식에 대해 자세히 설명이 되어있는 부분이 있습니다.
# 여기에서 나열된 인코딩 방식을 전부 웹 크롤링으로 가져와, 향후 csv 파일 읽을 때 하나씩 넣어보려고 합니다.
# 챕터 2는 웹 크롤링에 관한 부분이 아니므로, 크롤링 코드 해설은 스킵합니다.
import requests
from bs4 import BeautifulSoup
req = requests.get('https://docs.python.org/3/library/codecs.html#standard-encodings').content
bs1 = BeautifulSoup(req, 'html5lib')
bs2 = bs1.find('div', id='standard-encodings')
bs3 = bs2.find('table', class_='docutils align-center')
bs4 = bs3.find('tbody')
bs5 = bs4.findAll('tr')
codec_list = []
for i in bs5:
codec_list.append(i.find('p').text)
# 파이썬에서 데이터프레임을 다루는 도구인 pandas 를 가져와
# 향후 pd 라는 축약어로 사용하기로 합니다.
import pandas as pd
# codec_list 에는, 파이썬에서 사용 가능한 모든 인코딩 방식에 대한 정보가 들어있습니다.
# for 문은 in 을 기준으로 오른쪽에 있는 묶음에서 하나씩 뽑아와 왼쪽의 변수에 집어넣고
# 집어넣을 때마다 들여쓰기 된 부분을 실행하는 의미인 반복 기능을 수행하는 문법입니다.
for i in codec_list:
# try ~ except 는 문법에서 예외처리 라는 부분입니다.
try:
crime_anal_police = pd.read_csv('../data/02. crime_in_Seoul.csv', thousands=',', encoding=i)
print(i)
print(crime_anal_police.columns[:4])
except:
pass
# 위에서 발견한 cp949 라는 방식으로 인코딩을 하여 이후 과정을 진행합니다.(교재에는 euc-kr)
crime_anal_police = pd.read_csv('../data/02. crime_in_Seoul.csv', thousands=',', encoding='cp949')
crime_anal_police.head()
관서명
살인 발생
살인 검거
강도 발생
강도 검거
강간 발생
강간 검거
절도 발생
절도 검거
폭력 발생
폭력 검거
0
중부서
2
2
3
2
105
65
1395
477
1355
1170
1
종로서
3
3
6
5
115
98
1070
413
1278
1070
2
남대문서
1
0
6
4
65
46
1153
382
869
794
3
서대문서
2
2
5
4
154
124
1812
738
2056
1711
4
혜화서
3
2
5
4
96
63
1114
424
1015
861
# 너무나도 당연하게 pd. 뒤에 read_csv 라는 것을 사용하는데요
# 점 찍고 나서 뒤에 어떤 것들을 사용할 수 있는지 알아보는 방법을 한 가지 소개합니다.
dir(pd)
# pd.read_csv 라는 기능을 발견했다면, 이 기능을 어떻게 사용할 것인지 알아보는 방법도 소개합니다.
# help 를 사용하면 해당 도구의 개발자 분들께서 만들어놓은 도움말을 볼 수 있습니다.
# pd.read_csv() 소괄호 안에 어떤 것들이 들어갈 수 있고,
# 각각의 것들이 어떠한 의미를 갖고 있는지에 대한 내용을 담고 있습니다.
help(pd.read_csv)
Help on function read_csv in module pandas.io.parsers:
read_csv(filepath_or_buffer, sep=',', delimiter=None, header='infer', names=None, index_col=None, usecols=None, squeeze=False, prefix=None, mangle_dupe_cols=True, dtype=None, engine=None, converters=None, true_values=None, false_values=None, skipinitialspace=False, skiprows=None, skipfooter=0, nrows=None, na_values=None, keep_default_na=True, na_filter=True, verbose=False, skip_blank_lines=True, parse_dates=False, infer_datetime_format=False, keep_date_col=False, date_parser=None, dayfirst=False, iterator=False, chunksize=None, compression='infer', thousands=None, decimal=b'.', lineterminator=None, quotechar='"', quoting=0, doublequote=True, escapechar=None, comment=None, encoding=None, dialect=None, tupleize_cols=None, error_bad_lines=True, warn_bad_lines=True, delim_whitespace=False, low_memory=True, memory_map=False, float_precision=None)
Read a comma-separated values (csv) file into DataFrame.
Also supports optionally iterating or breaking of the file
into chunks.
Additional help can be found in the online docs for
`IO Tools <http://pandas.pydata.org/pandas-docs/stable/io.html>`_.
Parameters
----------
filepath_or_buffer : str, path object, or file-like object
Any valid string path is acceptable. The string could be a URL. Valid
URL schemes include http, ftp, s3, and file. For file URLs, a host is
expected. A local file could be: file://localhost/path/to/table.csv.
If you want to pass in a path object, pandas accepts either
``pathlib.Path`` or ``py._path.local.LocalPath``.
By file-like object, we refer to objects with a ``read()`` method, such as
a file handler (e.g. via builtin ``open`` function) or ``StringIO``.
sep : str, default ','
Delimiter to use. If sep is None, the C engine cannot automatically detect
the separator, but the Python parsing engine can, meaning the latter will
be used and automatically detect the separator by Python's builtin sniffer
tool, ``csv.Sniffer``. In addition, separators longer than 1 character and
different from ``'\s+'`` will be interpreted as regular expressions and
will also force the use of the Python parsing engine. Note that regex
delimiters are prone to ignoring quoted data. Regex example: ``'\r\t'``.
delimiter : str, default ``None``
Alias for sep.
header : int, list of int, default 'infer'
Row number(s) to use as the column names, and the start of the
data. Default behavior is to infer the column names: if no names
are passed the behavior is identical to ``header=0`` and column
names are inferred from the first line of the file, if column
names are passed explicitly then the behavior is identical to
``header=None``. Explicitly pass ``header=0`` to be able to
replace existing names. The header can be a list of integers that
specify row locations for a multi-index on the columns
e.g. [0,1,3]. Intervening rows that are not specified will be
skipped (e.g. 2 in this example is skipped). Note that this
parameter ignores commented lines and empty lines if
``skip_blank_lines=True``, so ``header=0`` denotes the first line of
data rather than the first line of the file.
names : array-like, optional
List of column names to use. If file contains no header row, then you
should explicitly pass ``header=None``. Duplicates in this list will cause
a ``UserWarning`` to be issued.
index_col : int, sequence or bool, optional
Column to use as the row labels of the DataFrame. If a sequence is given, a
MultiIndex is used. If you have a malformed file with delimiters at the end
of each line, you might consider ``index_col=False`` to force pandas to
not use the first column as the index (row names).
usecols : list-like or callable, optional
Return a subset of the columns. If list-like, all elements must either
be positional (i.e. integer indices into the document columns) or strings
that correspond to column names provided either by the user in `names` or
inferred from the document header row(s). For example, a valid list-like
`usecols` parameter would be ``[0, 1, 2]`` or ``['foo', 'bar', 'baz']``.
Element order is ignored, so ``usecols=[0, 1]`` is the same as ``[1, 0]``.
To instantiate a DataFrame from ``data`` with element order preserved use
``pd.read_csv(data, usecols=['foo', 'bar'])[['foo', 'bar']]`` for columns
in ``['foo', 'bar']`` order or
``pd.read_csv(data, usecols=['foo', 'bar'])[['bar', 'foo']]``
for ``['bar', 'foo']`` order.
If callable, the callable function will be evaluated against the column
names, returning names where the callable function evaluates to True. An
example of a valid callable argument would be ``lambda x: x.upper() in
['AAA', 'BBB', 'DDD']``. Using this parameter results in much faster
parsing time and lower memory usage.
squeeze : bool, default False
If the parsed data only contains one column then return a Series.
prefix : str, optional
Prefix to add to column numbers when no header, e.g. 'X' for X0, X1, ...
mangle_dupe_cols : bool, default True
Duplicate columns will be specified as 'X', 'X.1', ...'X.N', rather than
'X'...'X'. Passing in False will cause data to be overwritten if there
are duplicate names in the columns.
dtype : Type name or dict of column -> type, optional
Data type for data or columns. E.g. {'a': np.float64, 'b': np.int32,
'c': 'Int64'}
Use `str` or `object` together with suitable `na_values` settings
to preserve and not interpret dtype.
If converters are specified, they will be applied INSTEAD
of dtype conversion.
engine : {'c', 'python'}, optional
Parser engine to use. The C engine is faster while the python engine is
currently more feature-complete.
converters : dict, optional
Dict of functions for converting values in certain columns. Keys can either
be integers or column labels.
true_values : list, optional
Values to consider as True.
false_values : list, optional
Values to consider as False.
skipinitialspace : bool, default False
Skip spaces after delimiter.
skiprows : list-like, int or callable, optional
Line numbers to skip (0-indexed) or number of lines to skip (int)
at the start of the file.
If callable, the callable function will be evaluated against the row
indices, returning True if the row should be skipped and False otherwise.
An example of a valid callable argument would be ``lambda x: x in [0, 2]``.
skipfooter : int, default 0
Number of lines at bottom of file to skip (Unsupported with engine='c').
nrows : int, optional
Number of rows of file to read. Useful for reading pieces of large files.
na_values : scalar, str, list-like, or dict, optional
Additional strings to recognize as NA/NaN. If dict passed, specific
per-column NA values. By default the following values are interpreted as
NaN: '', '#N/A', '#N/A N/A', '#NA', '-1.#IND', '-1.#QNAN', '-NaN', '-nan',
'1.#IND', '1.#QNAN', 'N/A', 'NA', 'NULL', 'NaN', 'n/a', 'nan',
'null'.
keep_default_na : bool, default True
Whether or not to include the default NaN values when parsing the data.
Depending on whether `na_values` is passed in, the behavior is as follows:
* If `keep_default_na` is True, and `na_values` are specified, `na_values`
is appended to the default NaN values used for parsing.
* If `keep_default_na` is True, and `na_values` are not specified, only
the default NaN values are used for parsing.
* If `keep_default_na` is False, and `na_values` are specified, only
the NaN values specified `na_values` are used for parsing.
* If `keep_default_na` is False, and `na_values` are not specified, no
strings will be parsed as NaN.
Note that if `na_filter` is passed in as False, the `keep_default_na` and
`na_values` parameters will be ignored.
na_filter : bool, default True
Detect missing value markers (empty strings and the value of na_values). In
data without any NAs, passing na_filter=False can improve the performance
of reading a large file.
verbose : bool, default False
Indicate number of NA values placed in non-numeric columns.
skip_blank_lines : bool, default True
If True, skip over blank lines rather than interpreting as NaN values.
parse_dates : bool or list of int or names or list of lists or dict, default False
The behavior is as follows:
* boolean. If True -> try parsing the index.
* list of int or names. e.g. If [1, 2, 3] -> try parsing columns 1, 2, 3
each as a separate date column.
* list of lists. e.g. If [[1, 3]] -> combine columns 1 and 3 and parse as
a single date column.
* dict, e.g. {'foo' : [1, 3]} -> parse columns 1, 3 as date and call
result 'foo'
If a column or index cannot be represented as an array of datetimes,
say because of an unparseable value or a mixture of timezones, the column
or index will be returned unaltered as an object data type. For
non-standard datetime parsing, use ``pd.to_datetime`` after
``pd.read_csv``. To parse an index or column with a mixture of timezones,
specify ``date_parser`` to be a partially-applied
:func:`pandas.to_datetime` with ``utc=True``. See
:ref:`io.csv.mixed_timezones` for more.
Note: A fast-path exists for iso8601-formatted dates.
infer_datetime_format : bool, default False
If True and `parse_dates` is enabled, pandas will attempt to infer the
format of the datetime strings in the columns, and if it can be inferred,
switch to a faster method of parsing them. In some cases this can increase
the parsing speed by 5-10x.
keep_date_col : bool, default False
If True and `parse_dates` specifies combining multiple columns then
keep the original columns.
date_parser : function, optional
Function to use for converting a sequence of string columns to an array of
datetime instances. The default uses ``dateutil.parser.parser`` to do the
conversion. Pandas will try to call `date_parser` in three different ways,
advancing to the next if an exception occurs: 1) Pass one or more arrays
(as defined by `parse_dates`) as arguments; 2) concatenate (row-wise) the
string values from the columns defined by `parse_dates` into a single array
and pass that; and 3) call `date_parser` once for each row using one or
more strings (corresponding to the columns defined by `parse_dates`) as
arguments.
dayfirst : bool, default False
DD/MM format dates, international and European format.
iterator : bool, default False
Return TextFileReader object for iteration or getting chunks with
``get_chunk()``.
chunksize : int, optional
Return TextFileReader object for iteration.
See the `IO Tools docs
<http://pandas.pydata.org/pandas-docs/stable/io.html#io-chunking>`_
for more information on ``iterator`` and ``chunksize``.
compression : {'infer', 'gzip', 'bz2', 'zip', 'xz', None}, default 'infer'
For on-the-fly decompression of on-disk data. If 'infer' and
`filepath_or_buffer` is path-like, then detect compression from the
following extensions: '.gz', '.bz2', '.zip', or '.xz' (otherwise no
decompression). If using 'zip', the ZIP file must contain only one data
file to be read in. Set to None for no decompression.
.. versionadded:: 0.18.1 support for 'zip' and 'xz' compression.
thousands : str, optional
Thousands separator.
decimal : str, default '.'
Character to recognize as decimal point (e.g. use ',' for European data).
lineterminator : str (length 1), optional
Character to break file into lines. Only valid with C parser.
quotechar : str (length 1), optional
The character used to denote the start and end of a quoted item. Quoted
items can include the delimiter and it will be ignored.
quoting : int or csv.QUOTE_* instance, default 0
Control field quoting behavior per ``csv.QUOTE_*`` constants. Use one of
QUOTE_MINIMAL (0), QUOTE_ALL (1), QUOTE_NONNUMERIC (2) or QUOTE_NONE (3).
doublequote : bool, default ``True``
When quotechar is specified and quoting is not ``QUOTE_NONE``, indicate
whether or not to interpret two consecutive quotechar elements INSIDE a
field as a single ``quotechar`` element.
escapechar : str (length 1), optional
One-character string used to escape other characters.
comment : str, optional
Indicates remainder of line should not be parsed. If found at the beginning
of a line, the line will be ignored altogether. This parameter must be a
single character. Like empty lines (as long as ``skip_blank_lines=True``),
fully commented lines are ignored by the parameter `header` but not by
`skiprows`. For example, if ``comment='#'``, parsing
``#empty\na,b,c\n1,2,3`` with ``header=0`` will result in 'a,b,c' being
treated as the header.
encoding : str, optional
Encoding to use for UTF when reading/writing (ex. 'utf-8'). `List of Python
standard encodings
<https://docs.python.org/3/library/codecs.html#standard-encodings>`_ .
dialect : str or csv.Dialect, optional
If provided, this parameter will override values (default or not) for the
following parameters: `delimiter`, `doublequote`, `escapechar`,
`skipinitialspace`, `quotechar`, and `quoting`. If it is necessary to
override values, a ParserWarning will be issued. See csv.Dialect
documentation for more details.
tupleize_cols : bool, default False
Leave a list of tuples on columns as is (default is to convert to
a MultiIndex on the columns).
.. deprecated:: 0.21.0
This argument will be removed and will always convert to MultiIndex
error_bad_lines : bool, default True
Lines with too many fields (e.g. a csv line with too many commas) will by
default cause an exception to be raised, and no DataFrame will be returned.
If False, then these "bad lines" will dropped from the DataFrame that is
returned.
warn_bad_lines : bool, default True
If error_bad_lines is False, and warn_bad_lines is True, a warning for each
"bad line" will be output.
delim_whitespace : bool, default False
Specifies whether or not whitespace (e.g. ``' '`` or ``' '``) will be
used as the sep. Equivalent to setting ``sep='\s+'``. If this option
is set to True, nothing should be passed in for the ``delimiter``
parameter.
.. versionadded:: 0.18.1 support for the Python parser.
low_memory : bool, default True
Internally process the file in chunks, resulting in lower memory use
while parsing, but possibly mixed type inference. To ensure no mixed
types either set False, or specify the type with the `dtype` parameter.
Note that the entire file is read into a single DataFrame regardless,
use the `chunksize` or `iterator` parameter to return the data in chunks.
(Only valid with C parser).
memory_map : bool, default False
If a filepath is provided for `filepath_or_buffer`, map the file object
directly onto memory and access the data directly from there. Using this
option can improve performance because there is no longer any I/O overhead.
float_precision : str, optional
Specifies which converter the C engine should use for floating-point
values. The options are `None` for the ordinary converter,
`high` for the high-precision converter, and `round_trip` for the
round-trip converter.
Returns
-------
DataFrame or TextParser
A comma-separated values (csv) file is returned as two-dimensional
data structure with labeled axes.
See Also
--------
to_csv : Write DataFrame to a comma-separated values (csv) file.
read_csv : Read a comma-separated values (csv) file into DataFrame.
read_fwf : Read a table of fixed-width formatted lines into DataFrame.
Examples
--------
>>> pd.read_csv('data.csv') # doctest: +SKIP
pandas의 pivot_table 익히기
import pandas as pd
import numpy as np
#pandas 의 read_excel 기능을 이용하여 데이터 셋을 불러옵니다.
df = pd.read_excel("../data/02. sales-funnel.xlsx")
df.head()
Account
Name
Rep
Manager
Product
Quantity
Price
Status
0
714466
Trantow-Barrows
Craig Booker
Debra Henley
CPU
1
30000
presented
1
714466
Trantow-Barrows
Craig Booker
Debra Henley
Software
1
10000
presented
2
714466
Trantow-Barrows
Craig Booker
Debra Henley
Maintenance
2
5000
pending
3
737550
Fritsch, Russel and Anderson
Craig Booker
Debra Henley
CPU
1
35000
declined
4
146832
Kiehn-Spinka
Daniel Hilton
Debra Henley
CPU
2
65000
won
# 교재에서는 index 정렬시 피벗 테이블 사용한다고 되어 있습니다.
pd.pivot_table(df,index=["Name"])
Account
Price
Quantity
Name
Barton LLC
740150
35000
1.000000
Fritsch, Russel and Anderson
737550
35000
1.000000
Herman LLC
141962
65000
2.000000
Jerde-Hilpert
412290
5000
2.000000
Kassulke, Ondricka and Metz
307599
7000
3.000000
Keeling LLC
688981
100000
5.000000
Kiehn-Spinka
146832
65000
2.000000
Koepp Ltd
729833
35000
2.000000
Kulas Inc
218895
25000
1.500000
Purdy-Kunde
163416
30000
1.000000
Stokes LLC
239344
7500
1.000000
Trantow-Barrows
714466
15000
1.333333
# 멀티-인덱스 로도 사용이 가능합니다.
# 하지만 멀티 인덱스의 경우 순서가 중요합니다.
pd.pivot_table(df,index=["Name","Rep","Manager"])
Account
Price
Quantity
Name
Rep
Manager
Barton LLC
John Smith
Debra Henley
740150
35000
1.000000
Fritsch, Russel and Anderson
Craig Booker
Debra Henley
737550
35000
1.000000
Herman LLC
Cedric Moss
Fred Anderson
141962
65000
2.000000
Jerde-Hilpert
John Smith
Debra Henley
412290
5000
2.000000
Kassulke, Ondricka and Metz
Wendy Yule
Fred Anderson
307599
7000
3.000000
Keeling LLC
Wendy Yule
Fred Anderson
688981
100000
5.000000
Kiehn-Spinka
Daniel Hilton
Debra Henley
146832
65000
2.000000
Koepp Ltd
Wendy Yule
Fred Anderson
729833
35000
2.000000
Kulas Inc
Daniel Hilton
Debra Henley
218895
25000
1.500000
Purdy-Kunde
Cedric Moss
Fred Anderson
163416
30000
1.000000
Stokes LLC
Cedric Moss
Fred Anderson
239344
7500
1.000000
Trantow-Barrows
Craig Booker
Debra Henley
714466
15000
1.333333
# 그 이유는 순서에 따라서 묶는 기준이 달라지기 때문입니다.
# 교재에서는 Name 까지 묶지 않았지만, Name 까지 묶어서 처리하면 아래와 같습니다.
pd.pivot_table(df,index=["Manager","Rep","Name"])
Account
Price
Quantity
Manager
Rep
Name
Debra Henley
Craig Booker
Fritsch, Russel and Anderson
737550
35000
1.000000
Trantow-Barrows
714466
15000
1.333333
Daniel Hilton
Kiehn-Spinka
146832
65000
2.000000
Kulas Inc
218895
25000
1.500000
John Smith
Barton LLC
740150
35000
1.000000
Jerde-Hilpert
412290
5000
2.000000
Fred Anderson
Cedric Moss
Herman LLC
141962
65000
2.000000
Purdy-Kunde
163416
30000
1.000000
Stokes LLC
239344
7500
1.000000
Wendy Yule
Kassulke, Ondricka and Metz
307599
7000
3.000000
Keeling LLC
688981
100000
5.000000
Koepp Ltd
729833
35000
2.000000
# 보고자 하는 값을 특별히 정해서 넣을 수 도 있습니다.
# aggregate 시 디폴트 수식은 mean 입니다.
pd.pivot_table(df,index=["Manager","Rep"],values=["Price"])
Price
Manager
Rep
Debra Henley
Craig Booker
20000.000000
Daniel Hilton
38333.333333
John Smith
20000.000000
Fred Anderson
Cedric Moss
27500.000000
Wendy Yule
44250.000000
# aggregate 시 사용할 함수를 직접 지정할 수도 있습니다.
pd.pivot_table(df,index=["Manager","Rep"],values=["Price"],aggfunc=np.sum)
Price
Manager
Rep
Debra Henley
Craig Booker
80000
Daniel Hilton
115000
John Smith
40000
Fred Anderson
Cedric Moss
110000
Wendy Yule
177000
# aggfunc 에 들어가는 함수가 자주 쓰던 함수의 사용법과는 약간 다른 것을 알 수 있습니다.
# 함수는 만들 때 def 사용하고, 사용할 때 뒤에 소괄호를 붙였었는데, 여기에서는
# 함수(기능)을 집어넣는 것이지 실행하는 것이 아니므로 를 붙이지 않습니다.
# 이 부분은 파이썬 문법에서 클로저에 해당합니다.
pd.pivot_table(df,index=["Manager","Rep"],values=["Price"],aggfunc=[np.mean,len])
mean
len
Price
Price
Manager
Rep
Debra Henley
Craig Booker
20000.000000
4
Daniel Hilton
38333.333333
3
John Smith
20000.000000
2
Fred Anderson
Cedric Moss
27500.000000
4
Wendy Yule
44250.000000
4
# 위에서는 인덱스(행) 을 기준으로 피벗 테이블 하는 법을 알아보았습니다.
# 여기에서는 컬럼(열) 또한 기준으로 잡을 수 있다는 것을 보여줍니다.
# 지금의 경우, 결과로 나온 데이터에 공백(NaN) 이 많이 있음을 알 수 있는데
# 이를 sparse-matrix 라는 개념으로 설명하기도 합니다.
pd.pivot_table(df,index=["Manager","Rep"],values=["Price"],
columns=["Product"],aggfunc=[np.sum])
sum
Price
Product
CPU
Maintenance
Monitor
Software
Manager
Rep
Debra Henley
Craig Booker
65000.0
5000.0
NaN
10000.0
Daniel Hilton
105000.0
NaN
NaN
10000.0
John Smith
35000.0
5000.0
NaN
NaN
Fred Anderson
Cedric Moss
95000.0
5000.0
NaN
10000.0
Wendy Yule
165000.0
7000.0
5000.0
NaN
# 결측치 처리를 간단하게 하는 방법에 대해 다루고 있습니다.
# .pivot_table() 에는 null 값을 일괄 처리하는 기능이 있습니다.
# 이는 fill_value 라는 키워드로 넣어주게 됩니다.
pd.pivot_table(df,index=["Manager","Rep"],values=["Price"],
columns=["Product"],aggfunc=[np.sum],fill_value=0)
sum
Price
Product
CPU
Maintenance
Monitor
Software
Manager
Rep
Debra Henley
Craig Booker
65000
5000
0
10000
Daniel Hilton
105000
0
0
10000
John Smith
35000
5000
0
0
Fred Anderson
Cedric Moss
95000
5000
0
10000
Wendy Yule
165000
7000
5000
0
# 바로 위의 코드와 다른 점은 멀티인덱스가 2 -> 3 으로 한 단계 더 들어갔습니다.
# 컬럼을 지정하지 않았습니다.
# 보고자 하는 값을 price -> price + quantity 로 하나 늘렸습니다.
pd.pivot_table(df,index=["Manager","Rep","Product"],
values=["Price","Quantity"],aggfunc=[np.sum],fill_value=0)
sum
Price
Quantity
Manager
Rep
Product
Debra Henley
Craig Booker
CPU
65000
2
Maintenance
5000
2
Software
10000
1
Daniel Hilton
CPU
105000
4
Software
10000
1
John Smith
CPU
35000
1
Maintenance
5000
2
Fred Anderson
Cedric Moss
CPU
95000
3
Maintenance
5000
1
Software
10000
1
Wendy Yule
CPU
165000
7
Maintenance
7000
3
Monitor
5000
2
# 위의 코드와 다른 점은 aggregation 시 적용할 함수를 하나 더 늘리고
# margins=True 라는 옵션을 넣은 모양입니다.
# 이 때 margins 이라는 옵션이 어떠한 역할을 수행하는 지 알아보고 싶다면?
pd.pivot_table(df,index=["Manager","Rep","Product"],
values=["Price","Quantity"],
aggfunc=[np.sum,np.mean],fill_value=0,margins=True)
sum
mean
Price
Quantity
Price
Quantity
Manager
Rep
Product
Debra Henley
Craig Booker
CPU
65000
2
32500
1.000000
Maintenance
5000
2
5000
2.000000
Software
10000
1
10000
1.000000
Daniel Hilton
CPU
105000
4
52500
2.000000
Software
10000
1
10000
1.000000
John Smith
CPU
35000
1
35000
1.000000
Maintenance
5000
2
5000
2.000000
Fred Anderson
Cedric Moss
CPU
95000
3
47500
1.500000
Maintenance
5000
1
5000
1.000000
Software
10000
1
10000
1.000000
Wendy Yule
CPU
165000
7
82500
3.500000
Maintenance
7000
3
7000
3.000000
Monitor
5000
2
5000
2.000000
All
522000
30
30705
1.764706
# margins 옵션은 디폴트값이 False 임을 알 수 있습니다.
# 설명을 읽어보면, subtotal 과 grand totals 정보를 추가하는 기능임을 알 수 있습니다.
help(pd.pivot_table)
Help on function pivot_table in module pandas.core.reshape.pivot:
pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All')
Create a spreadsheet-style pivot table as a DataFrame. The levels in
the pivot table will be stored in MultiIndex objects (hierarchical
indexes) on the index and columns of the result DataFrame.
Parameters
----------
data : DataFrame
values : column to aggregate, optional
index : column, Grouper, array, or list of the previous
If an array is passed, it must be the same length as the data. The
list can contain any of the other types (except list).
Keys to group by on the pivot table index. If an array is passed,
it is being used as the same manner as column values.
columns : column, Grouper, array, or list of the previous
If an array is passed, it must be the same length as the data. The
list can contain any of the other types (except list).
Keys to group by on the pivot table column. If an array is passed,
it is being used as the same manner as column values.
aggfunc : function, list of functions, dict, default numpy.mean
If list of functions passed, the resulting pivot table will have
hierarchical columns whose top level are the function names
(inferred from the function objects themselves)
If dict is passed, the key is column to aggregate and value
is function or list of functions
fill_value : scalar, default None
Value to replace missing values with
margins : boolean, default False
Add all row / columns (e.g. for subtotal / grand totals)
dropna : boolean, default True
Do not include columns whose entries are all NaN
margins_name : string, default 'All'
Name of the row / column that will contain the totals
when margins is True.
Returns
-------
table : DataFrame
See Also
--------
DataFrame.pivot : Pivot without aggregation that can handle
non-numeric data.
Examples
--------
>>> df = pd.DataFrame({"A": ["foo", "foo", "foo", "foo", "foo",
... "bar", "bar", "bar", "bar"],
... "B": ["one", "one", "one", "two", "two",
... "one", "one", "two", "two"],
... "C": ["small", "large", "large", "small",
... "small", "large", "small", "small",
... "large"],
... "D": [1, 2, 2, 3, 3, 4, 5, 6, 7],
... "E": [2, 4, 5, 5, 6, 6, 8, 9, 9]})
>>> df
A B C D E
0 foo one small 1 2
1 foo one large 2 4
2 foo one large 2 5
3 foo two small 3 5
4 foo two small 3 6
5 bar one large 4 6
6 bar one small 5 8
7 bar two small 6 9
8 bar two large 7 9
This first example aggregates values by taking the sum.
>>> table = pivot_table(df, values='D', index=['A', 'B'],
... columns=['C'], aggfunc=np.sum)
>>> table
C large small
A B
bar one 4 5
two 7 6
foo one 4 1
two NaN 6
We can also fill missing values using the `fill_value` parameter.
>>> table = pivot_table(df, values='D', index=['A', 'B'],
... columns=['C'], aggfunc=np.sum, fill_value=0)
>>> table
C large small
A B
bar one 4 5
two 7 6
foo one 4 1
two 0 6
The next example aggregates by taking the mean across multiple columns.
>>> table = pivot_table(df, values=['D', 'E'], index=['A', 'C'],
... aggfunc={'D': np.mean,
... 'E': np.mean})
>>> table
D E
mean mean
A C
bar large 5.500000 7.500000
small 5.500000 8.500000
foo large 2.000000 4.500000
small 2.333333 4.333333
We can also calculate multiple types of aggregations for any given
value column.
>>> table = pivot_table(df, values=['D', 'E'], index=['A', 'C'],
... aggfunc={'D': np.mean,
... 'E': [min, max, np.mean]})
>>> table
D E
mean max mean min
A C
bar large 5.500000 9 7.500000 6
small 5.500000 9 8.500000 8
foo large 2.000000 5 4.500000 4
small 2.333333 6 4.333333 2
범죄 데이터 구별로 정리하기
# 여기에서 데이터 셋에 Unnamed: 0 이 있는 이유는
# 처음에 이 데이터 셋을 만들 때 저장시 index=False 옵션을 넣지 않아서
# 데이터를 저장할 때 디폴트 설정으로 인덱스가 데이터 셋에 추가되기 때문입니다.
import numpy as np
crime_anal_raw = pd.read_csv('../data/02. crime_in_Seoul_include_gu_name.csv',
encoding='utf-8')
crime_anal_raw.head()
Unnamed: 0
관서명
살인 발생
살인 검거
강도 발생
강도 검거
강간 발생
강간 검거
절도 발생
절도 검거
폭력 발생
폭력 검거
구별
0
0
중부서
2
2
3
2
105
65
1395
477
1355
1170
중구
1
1
종로서
3
3
6
5
115
98
1070
413
1278
1070
종로구
2
2
남대문서
1
0
6
4
65
46
1153
382
869
794
중구
3
3
서대문서
2
2
5
4
154
124
1812
738
2056
1711
서대문구
4
4
혜화서
3
2
5
4
96
63
1114
424
1015
861
종로구
# 그래서 이 예제에서는 index_col=0 옵션을 통해
# 데이터 셋의 컬럼 중에서 0 번째(Untitled: 0) 을 인덱스로 사용하겠다고
# 강제 지정을 하여 구현하였습니다.
crime_anal_raw = pd.read_csv('../data/02. crime_in_Seoul_include_gu_name.csv',
encoding='utf-8', index_col=0)
# 이전에 다룬 피벗 테이블 활용에서 나온 문법과 동일합니다.
crime_anal = pd.pivot_table(crime_anal_raw, index='구별', aggfunc=np.sum)
crime_anal.head()
강간 검거
강간 발생
강도 검거
강도 발생
살인 검거
살인 발생
절도 검거
절도 발생
폭력 검거
폭력 발생
구별
강남구
349
449
18
21
10
13
1650
3850
3705
4284
강동구
123
156
8
6
3
4
789
2366
2248
2712
강북구
126
153
13
14
8
7
618
1434
2348
2649
관악구
221
320
14
12
8
9
827
2706
2642
3298
광진구
220
240
26
14
4
4
1277
3026
2180
2625
# 딕셔너리에서 새로운 키에 값을 저장할 수 있는 것처럼,
# 데이터프레임에서 새로운 키(컬럼)에 값을 지정할 수 있습니다.
# 원본 데이터 프레임에서는 검거율 이라는 컬럼이 존재하지 않고
# 기존에 존재하는 정보들로부터 검거율 이라고 하는 새로운 파생변수를 만들어줍니다.
crime_anal['강간검거율'] = crime_anal['강간 검거']/crime_anal['강간 발생']*100
crime_anal['강도검거율'] = crime_anal['강도 검거']/crime_anal['강도 발생']*100
crime_anal['살인검거율'] = crime_anal['살인 검거']/crime_anal['살인 발생']*100
crime_anal['절도검거율'] = crime_anal['절도 검거']/crime_anal['절도 발생']*100
crime_anal['폭력검거율'] = crime_anal['폭력 검거']/crime_anal['폭력 발생']*100
del crime_anal['강간 검거']
del crime_anal['강도 검거']
del crime_anal['살인 검거']
del crime_anal['절도 검거']
del crime_anal['폭력 검거']
crime_anal.head()
강간 발생
강도 발생
살인 발생
절도 발생
폭력 발생
강간검거율
강도검거율
살인검거율
절도검거율
폭력검거율
구별
강남구
449
21
13
3850
4284
77.728285
85.714286
76.923077
42.857143
86.484594
강동구
156
6
4
2366
2712
78.846154
133.333333
75.000000
33.347422
82.890855
강북구
153
14
7
1434
2649
82.352941
92.857143
114.285714
43.096234
88.637222
관악구
320
12
9
2706
3298
69.062500
116.666667
88.888889
30.561715
80.109157
광진구
240
14
4
3026
2625
91.666667
185.714286
100.000000
42.200925
83.047619
# .loc 문법에 대한 설명입니다.
# .loc[불리언, 컬럼명] = 채우고자 하는 값 입니다.
# 이번 코드의 경우 해당 컬럼의 row 값이 100 이상인 경우, 해당 컬럼의 row 값은 100으로 바꾸겠다는 의미입니다.
# 교재에서는 발생일시와 검거일시의 차이 때문에 이월된 사건이 포함된 이유라고 설명합니다.
con_list = ['강간검거율', '강도검거율', '살인검거율', '절도검거율', '폭력검거율']
for column in con_list:
crime_anal.loc[crime_anal[column] > 100, column] = 100
crime_anal.head()
강간 발생
강도 발생
살인 발생
절도 발생
폭력 발생
강간검거율
강도검거율
살인검거율
절도검거율
폭력검거율
구별
강남구
449
21
13
3850
4284
77.728285
85.714286
76.923077
42.857143
86.484594
강동구
156
6
4
2366
2712
78.846154
100.000000
75.000000
33.347422
82.890855
강북구
153
14
7
1434
2649
82.352941
92.857143
100.000000
43.096234
88.637222
관악구
320
12
9
2706
3298
69.062500
100.000000
88.888889
30.561715
80.109157
광진구
240
14
4
3026
2625
91.666667
100.000000
100.000000
42.200925
83.047619
# 컬럼의 이름을 바꿔주는 방법은 딕셔너리의 키워드 : 값 개념으로 적용합니다.
# 키워드 로 조회하여 값을 조회하는 딕셔너리의 특징입니다.
# 원래 있던 컬럼명을 키워드 로 사용하고, 바꾸고자 하는 내용을 값으로 집어넣습니다.
crime_anal.rename(columns = {'강간 발생':'강간',
'강도 발생':'강도',
'살인 발생':'살인',
'절도 발생':'절도',
'폭력 발생':'폭력'}, inplace=True)
crime_anal.head()
강간
강도
살인
절도
폭력
강간검거율
강도검거율
살인검거율
절도검거율
폭력검거율
구별
강남구
449
21
13
3850
4284
77.728285
85.714286
76.923077
42.857143
86.484594
강동구
156
6
4
2366
2712
78.846154
100.000000
75.000000
33.347422
82.890855
강북구
153
14
7
1434
2649
82.352941
92.857143
100.000000
43.096234
88.637222
관악구
320
12
9
2706
3298
69.062500
100.000000
88.888889
30.561715
80.109157
광진구
240
14
4
3026
2625
91.666667
100.000000
100.000000
42.200925
83.047619
# 파이썬에서 sklearn 이라고 하는 데이터 분석을 위해 사용하는 도구가 있습니다.
# 이 도구에서 preprocessing 이라는 부분을 불러옵니다.
from sklearn import preprocessing
# 전처리 하고자 하는 컬럼들을 리스트에 넣어서, 이후 해당 컬럼만 사용하고자 할 때 이용합니다.
col = ['강간', '강도', '살인', '절도', '폭력']
# .values 는 값들만 불러오겠다는 의미입니다.
# 마찬가지로, .columns 는 컬럼(키워드) 만 가져온다는 의미입니다.
x = crime_anal[col].values
# sklearn 의 preprocessing 으로부터 MinMaxScaler 함수를 가져와
# min_max_scaler 라는 이름으로 이 기능을 저장합니다.
min_max_scaler = preprocessing.MinMaxScaler()
# x.astype은 데이터 타입을 바꿔준다는 의미입니다.
# 여기에서는 실수(float) 로 바꿔줌을 의미합니다.
x_scaled = min_max_scaler.fit_transform(x.astype(float))
# x_scaled 는 정규화 된 값 만 들어있는 데이터입니다.
# 데이터프레임 형식이 아니기 때문에 인덱스와 컬럼명이 명시되지 않습니다.
# 이를 데이터 프레임 형식으로 바꿔주기 위한 기능이 pd.DataFrame 입니다.
crime_anal_norm = pd.DataFrame(x_scaled, columns = col, index = crime_anal.index)
# 이렇게 만든 데이터프레임에, 기존에 처리한 파생변수인 검거율을 집어넣기 위한 코드입니다.
# 검거율 정보가 전부 들어있는 리스트를 만들어 줍니다.
col2 = ['강간검거율', '강도검거율', '살인검거율', '절도검거율', '폭력검거율']
# 딕셔너리 안 새로운 키에 값을 집어넣는 방법과 정확히 동일합니다.
# 기존에 있던 데이터프레임인 crime_anal 으로부터 검거율 정보를 가져와
# 새로 만든 데이터 프레임에 키 : 값 형태로 집어넣습니다.
crime_anal_norm[col2] = crime_anal[col2]
crime_anal_norm.head()
강간
강도
살인
절도
폭력
강간검거율
강도검거율
살인검거율
절도검거율
폭력검거율
구별
강남구
1.000000
0.941176
0.916667
0.953472
0.661386
77.728285
85.714286
76.923077
42.857143
86.484594
강동구
0.155620
0.058824
0.166667
0.445775
0.289667
78.846154
100.000000
75.000000
33.347422
82.890855
강북구
0.146974
0.529412
0.416667
0.126924
0.274769
82.352941
92.857143
100.000000
43.096234
88.637222
관악구
0.628242
0.411765
0.583333
0.562094
0.428234
69.062500
100.000000
88.888889
30.561715
80.109157
광진구
0.397695
0.529412
0.166667
0.671570
0.269094
91.666667
100.000000
100.000000
42.200925
83.047619
# 구별 CCTV 정보를 불러와 reault_CCTV 변수에 집어넣습니다.
result_CCTV = pd.read_csv('../data/01. CCTV_result.csv', encoding='UTF-8',
index_col='구별')
# 새로 만들 데이터 프레임에 CCTV 정보 또한 집어넣습니다.
# 바로 위에서 검거율을 집어넣는 방법과 동일합니다.
crime_anal_norm[['인구수', 'CCTV']] = result_CCTV[['인구수', '소계']]
crime_anal_norm.head()
강간
강도
살인
절도
폭력
강간검거율
강도검거율
살인검거율
절도검거율
폭력검거율
인구수
CCTV
구별
강남구
1.000000
0.941176
0.916667
0.953472
0.661386
77.728285
85.714286
76.923077
42.857143
86.484594
570500.0
2780
강동구
0.155620
0.058824
0.166667
0.445775
0.289667
78.846154
100.000000
75.000000
33.347422
82.890855
453233.0
773
강북구
0.146974
0.529412
0.416667
0.126924
0.274769
82.352941
92.857143
100.000000
43.096234
88.637222
330192.0
748
관악구
0.628242
0.411765
0.583333
0.562094
0.428234
69.062500
100.000000
88.888889
30.561715
80.109157
525515.0
1496
광진구
0.397695
0.529412
0.166667
0.671570
0.269094
91.666667
100.000000
100.000000
42.200925
83.047619
372164.0
707
# 모든 범죄 사실들을 구별로 더하여 범죄 라는 컬럼을 만들기 위한 코드입니다.
# 여기에서 주목한 부분은 axis=1 에 대한 것입니다.
# axis=1 은 행을 기준으로, 0 은 열을 기준으로 한다는 의미입니다.
col = ['강간','강도','살인','절도','폭력']
crime_anal_norm['범죄'] = np.sum(crime_anal_norm[col], axis=1)
crime_anal_norm.head()
강간
강도
살인
절도
폭력
강간검거율
강도검거율
살인검거율
절도검거율
폭력검거율
인구수
CCTV
범죄
구별
강남구
1.000000
0.941176
0.916667
0.953472
0.661386
77.728285
85.714286
76.923077
42.857143
86.484594
570500.0
2780
4.472701
강동구
0.155620
0.058824
0.166667
0.445775
0.289667
78.846154
100.000000
75.000000
33.347422
82.890855
453233.0
773
1.116551
강북구
0.146974
0.529412
0.416667
0.126924
0.274769
82.352941
92.857143
100.000000
43.096234
88.637222
330192.0
748
1.494746
관악구
0.628242
0.411765
0.583333
0.562094
0.428234
69.062500
100.000000
88.888889
30.561715
80.109157
525515.0
1496
2.613667
광진구
0.397695
0.529412
0.166667
0.671570
0.269094
91.666667
100.000000
100.000000
42.200925
83.047619
372164.0
707
2.034438
# 위의 범죄 컬럼에 이어서, 검거율을 더한 검거 라는 컬럼을 만들기 위한 코드입니다.
col = ['강간검거율','강도검거율','살인검거율','절도검거율','폭력검거율']
crime_anal_norm['검거'] = np.sum(crime_anal_norm[col], axis=1)
crime_anal_norm.head()
강간
강도
살인
절도
폭력
강간검거율
강도검거율
살인검거율
절도검거율
폭력검거율
인구수
CCTV
범죄
검거
구별
강남구
1.000000
0.941176
0.916667
0.953472
0.661386
77.728285
85.714286
76.923077
42.857143
86.484594
570500.0
2780
4.472701
369.707384
강동구
0.155620
0.058824
0.166667
0.445775
0.289667
78.846154
100.000000
75.000000
33.347422
82.890855
453233.0
773
1.116551
370.084431
강북구
0.146974
0.529412
0.416667
0.126924
0.274769
82.352941
92.857143
100.000000
43.096234
88.637222
330192.0
748
1.494746
406.943540
관악구
0.628242
0.411765
0.583333
0.562094
0.428234
69.062500
100.000000
88.888889
30.561715
80.109157
525515.0
1496
2.613667
368.622261
광진구
0.397695
0.529412
0.166667
0.671570
0.269094
91.666667
100.000000
100.000000
42.200925
83.047619
372164.0
707
2.034438
416.915211
# 전처리 단계가 전부 끝난 이후, 잘 처리되었음을 확인해 줍니다.
crime_anal_norm
강간
강도
살인
절도
폭력
강간검거율
강도검거율
살인검거율
절도검거율
폭력검거율
인구수
CCTV
범죄
검거
구별
강남구
1.000000
0.941176
0.916667
0.953472
0.661386
77.728285
85.714286
76.923077
42.857143
86.484594
570500.0
2780
4.472701
369.707384
강동구
0.155620
0.058824
0.166667
0.445775
0.289667
78.846154
100.000000
75.000000
33.347422
82.890855
453233.0
773
1.116551
370.084431
강북구
0.146974
0.529412
0.416667
0.126924
0.274769
82.352941
92.857143
100.000000
43.096234
88.637222
330192.0
748
1.494746
406.943540
관악구
0.628242
0.411765
0.583333
0.562094
0.428234
69.062500
100.000000
88.888889
30.561715
80.109157
525515.0
1496
2.613667
368.622261
광진구
0.397695
0.529412
0.166667
0.671570
0.269094
91.666667
100.000000
100.000000
42.200925
83.047619
372164.0
707
2.034438
416.915211
구로구
0.515850
0.588235
0.500000
0.435169
0.359423
58.362989
73.333333
75.000000
38.072805
80.877951
447874.0
1561
2.398678
325.647079
금천구
0.141210
0.058824
0.083333
0.172426
0.134074
80.794702
100.000000
100.000000
56.668794
86.465433
255082.0
1015
0.589867
423.928929
노원구
0.273775
0.117647
0.666667
0.386589
0.292268
61.421320
100.000000
100.000000
36.525308
85.530665
569384.0
1265
1.736946
383.477292
도봉구
0.000000
0.235294
0.083333
0.000000
0.000000
100.000000
100.000000
100.000000
44.967074
87.626093
348646.0
485
0.318627
432.593167
동대문구
0.204611
0.470588
0.250000
0.314061
0.250887
84.393064
100.000000
100.000000
41.090358
87.401884
369496.0
1294
1.490147
412.885306
동작구
0.527378
0.235294
0.250000
0.274376
0.100024
48.771930
55.555556
100.000000
35.442359
83.089005
412520.0
1091
1.387071
322.858850
마포구
0.553314
0.529412
0.500000
0.510434
0.353748
84.013605
71.428571
100.000000
31.819961
84.445189
389649.0
574
2.446908
371.707327
서대문구
0.149856
0.000000
0.000000
0.256244
0.134547
80.519481
80.000000
100.000000
40.728477
83.219844
327163.0
962
0.540647
384.467802
서초구
0.838617
0.235294
0.500000
0.537804
0.215654
63.358779
66.666667
75.000000
41.404175
87.453105
450310.0
1930
2.327368
333.882725
성동구
0.069164
0.235294
0.166667
0.186110
0.029558
94.444444
88.888889
100.000000
37.149969
86.538462
311244.0
1062
0.686793
407.021764
성북구
0.138329
0.000000
0.250000
0.247007
0.170726
82.666667
80.000000
100.000000
41.512605
83.974649
461260.0
1464
0.806061
388.153921
송파구
0.340058
0.470588
0.750000
0.744441
0.427524
80.909091
76.923077
90.909091
34.856437
84.552352
667483.0
618
2.732611
368.150048
양천구
0.806916
0.823529
0.666667
1.000000
1.000000
77.486911
84.210526
100.000000
48.469644
83.065080
479978.0
2034
4.297113
393.232162
영등포구
0.556196
1.000000
1.000000
0.650359
0.493024
62.033898
90.909091
85.714286
32.995951
82.894737
402985.0
904
3.699580
354.547963
용산구
0.265130
0.529412
0.250000
0.169004
0.133128
89.175258
100.000000
100.000000
37.700706
83.121951
244203.0
1624
1.346674
409.997915
은평구
0.184438
0.235294
0.083333
0.291139
0.275715
84.939759
66.666667
100.000000
37.147335
86.920467
494388.0
1873
1.069920
375.674229
종로구
0.314121
0.352941
0.333333
0.383510
0.190589
76.303318
81.818182
83.333333
38.324176
84.212822
162820.0
1002
1.574494
363.991830
중구
0.195965
0.235294
0.083333
0.508040
0.174273
65.294118
66.666667
66.666667
33.712716
88.309353
133240.0
671
1.196905
320.649519
중랑구
0.244957
0.352941
0.916667
0.366746
0.321589
79.144385
81.818182
92.307692
38.829040
84.545135
414503.0
660
2.202900
376.644434
seaborn
# 파이썬의 시각화를 담당하는 가장 기초적인 도구인
# matplotlib 의 pyplot 을 불러와 향후 plt 라는 축약어로 사용하기로 합니다.
import matplotlib.pyplot as plt
# 이 명령어가 있는 이유는 주피터 노트북에서는
# 디폴트 값으로 화면에 그래프를 보여주지 않게 되어있는데,
# 이를 화면에 바로바로 띄워주게 만들어주기 위함입니다.
%matplotlib inline
# 파이썬에서 예쁘게 그래프를 그려주는 seaborn 을 불러와,
# 이를 향후 sns 라는 축약어로 사용하기로 합니다.
import seaborn as sns
# np.linspace(처음, 끝, 몇 개의 간격으로 쪼갤 것인가?)
# 향후 xy 2차원 그래프에서 x축(가로축) 으로 사용합니다.
x = np.linspace(0, 14, 100)
# numpy 에서는 이공계 학부생 수준에서 나올만한 함수들은 어지간한 것들이 전부 들어있습니다.
# np.sin() 은 numpy 안에 들어있는 사인함수를 의미합니다.
# mapping 개념입니다.
y1 = np.sin(x)
# np.sin(x) 를 기준으로 아래 함수들을 해설하자면,
# 앞에 상수를 곱한 것은 사인함수의 amplitude 를 의미합니다.
# x에 상수를 더한 것은 사인함수의 phase-shift 를 의미합니다.
y2 = 2*np.sin(x+0.5)
y3 = 3*np.sin(x+1.0)
y4 = 4*np.sin(x+1.5)
# 해당 시각화의 크기를 결정하는 코드입니다.
plt.figure(figsize=(10,6))
# plt.plot() 은 간단한 lineplot 을 그리는 함수입니다.
# 같은 x 축을 공유해서 보고자 하기 때문에 x 가 동일합니다.
plt.plot(x,y1, x,y2, x,y3, x,y4)
# plt.show() 는 그래프를 보겠다는 의미이지만,
# 코드를 생략해도 그래프가 보입니다.
plt.show()
# seaborn 은 앞서 설명한 바와 같이, 예쁘게 그림을 그려주는 도구입니다.
# 따라서 테마 또한 설정할 수 있는데, 이 예제에서는 white 라는 스타일을 사용하였습니다.
# 배경색을 하얀색으로 설정한다는 의미를 갖고 있습니다.
sns.set_style("white")
plt.figure(figsize=(10,6))
plt.plot(x,y1, x,y2, x,y3, x,y4)
sns.despine()
plt.show()
# 이 예제는 배경색을 어둡게 하는 스타일을 적용한다는 의미입니다.
sns.set_style("dark")
plt.figure(figsize=(10,6))
plt.plot(x,y1, x,y2, x,y3, x,y4)
plt.show()
# R 에서의 grid 와 동일합니다.
sns.set_style("whitegrid")
plt.figure(figsize=(10,6))
plt.plot(x,y1, x,y2, x,y3, x,y4)
plt.show()
plt.figure(figsize=(10,6))
plt.plot(x,y1, x,y2, x,y3, x,y4)
sns.despine(offset=10)
'''
이렇게 생소한 기능을 보게 된다면, help() 를 이용하여 세부사항을 확인합니다.
아래는, 세부사항에서의 offset 옵션에 대한 설명입니다.
offset : int or dict, optional
Absolute distance, in points, spines should be moved away
from the axes (negative values move spines inward). A single value
applies to all spines; a dict can be used to set offset values per
side.
'''
plt.show()
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
sns.set_style("whitegrid")
%matplotlib inline
# seaborn, sklearn 등에는 데이터사이언스 입문자를 위한 데이터 셋들이 기본적으로 탑재되어 있고,
# 지금은 tips 라고 하는 데이터 셋을 불러온다는 의미입니다.
# 이 데이터 셋의 목적은, 흡연자와 비흡연자간 음식점 종업원에게 주는 팁에 유의미한 차이가 있는지를 보기 위함입니다.
tips = sns.load_dataset("tips")
tips.head(5)
total_bill
tip
sex
smoker
day
time
size
0
16.99
1.01
Female
No
Sun
Dinner
2
1
10.34
1.66
Male
No
Sun
Dinner
3
2
21.01
3.50
Male
No
Sun
Dinner
3
3
23.68
3.31
Male
No
Sun
Dinner
2
4
24.59
3.61
Female
No
Sun
Dinner
4
sns.set_style("whitegrid")
plt.figure(figsize=(8,6))
# tips 변수에 total_bill 컬럼을 가져와 boxplot 을 그리기 위한 재료로 집어넣습니다.
sns.boxplot(x=tips["total_bill"])
plt.show()
plt.figure(figsize=(8,6))
# boxplot 상 x 축과 y 축을 따로따로 지정해 시각화 합니다.
# x 는 nominal variable 이고, 4 가지 경우의 수가 있습니다.
# 일주일 전체의 정보가 아닌, 목 ~ 일까지의 정보만 있음을 알 수 있습니다.
sns.boxplot(x="day", y="total_bill", data=tips)
plt.show()
plt.figure(figsize=(8,6))
# hue 라는 단어는 seaborn 에서만 있는 키워드 옵션입니다.
# 한 시각화 안에서 차원을 추가하는 역할을 수행합니다.(nominal variable을 추가합니다.)
sns.boxplot(x="day", y="total_bill", hue="smoker", data=tips, palette="Set3")
plt.show()
plt.figure(figsize=(8,6))
# 값의 크기에 해당하는 위치에 점을 찍어 표현하는 시각화의 경우
# 데이터가 몰려있을 때 점 끼리 겹치게 되므로 정보에 대한 설명력이 떨어지는 단점이 있습니다.
# swarmplot 은 이 문제를 해결하기 위해 직교벡터에 해당하는 차원을 하나 추가하여
# 데이터가 몰려있는 경우 직교성분 값을 주어 데이터 쏠림에 의한 설명력 저하를 막았습니다.
sns.swarmplot(x="day", y="total_bill", data=tips, color=".5")
plt.show()
# 이 swarmplot 을 boxplot 과 겹쳐 그려 시각화 하는 코드 입니다.
# 박스플롯은 quantile 과 outlier 정보만 들어있지만
# swarmplot 은 데이터의 분포 또한 알 수 있기 때문에 결합한 것입니다.
plt.figure(figsize=(8,6))
sns.boxplot(x="day", y="total_bill", data=tips)
sns.swarmplot(x="day", y="total_bill", data=tips, color=".25")
plt.show()
# 코드 내용이 중복이므로, 스킵합니다.
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
tips = sns.load_dataset("tips")
tips.head(5)
total_bill
tip
sex
smoker
day
time
size
0
16.99
1.01
Female
No
Sun
Dinner
2
1
10.34
1.66
Male
No
Sun
Dinner
3
2
21.01
3.50
Male
No
Sun
Dinner
3
3
23.68
3.31
Male
No
Sun
Dinner
2
4
24.59
3.61
Female
No
Sun
Dinner
4
sns.set_style("darkgrid")
# sns.lmplot 은 산점도를 그리고, regression 을 해 주는 그래프 입니다.
# 교재에서는 ci 를 잡아준다고 했지만 코드에 따로 명시되지는 않았습니다.
# ci(Confidence Interval) 은 디폴트 값으로 95가 들어있기 때문입니다.
sns.lmplot(x="total_bill", y="tip", data=tips, size=7)
plt.show()
C:\Users\one\AppData\Local\Continuum\anaconda3\lib\site-packages\seaborn\regression.py:546: UserWarning: The `size` paramter has been renamed to `height`; please update your code.
warnings.warn(msg, UserWarning)
# 이를 nominal variable 인 smoker 로 차원을 하나 더 넣어서 볼 수도 있습니다.
sns.lmplot(x="total_bill", y="tip", hue="smoker", data=tips, size=7)
plt.show()
# palette 는 lmplot 의 색상 스타일을 지정하는 옵션입니다.
# https://seaborn.pydata.org/generated/seaborn.color_palette.html#seaborn.color_palette
sns.lmplot(x="total_bill", y="tip", hue="smoker", data=tips, palette="Set1", size=7)
plt.show()
# 공식 문서 내용:
# Create an array of the given shape and populate it with random samples from a uniform distribution over [0, 1).
# 유니폼 분포를 생성하는 함수이고, (10, 12) 는 해당 분포를 10 x 12 dimension 으로 만든다는 의미입니다.
uniform_data = np.random.rand(10, 12)
uniform_data
# seaborn 에서는 열 분포 시각화 방식을 기본으로 제공합니다.
# 유니폼 분포가 10 행 12 열 이었기 때문에, 히트맵 또한 같은 dimension 으로 나왔습니다.
sns.heatmap(uniform_data)
plt.show()
# seaborn document 상 vmin, vmax 내용:
# Values to anchor the colormap, otherwise they are inferred from the data and other keyword arguments.
# scale 상 window 설정을 위한 옵션입니다.
sns.heatmap(uniform_data, vmin=0, vmax=1)
plt.show()
# index, column, value 값을 각각 넣어서 피벗 테이블을 만들었습니다.
# 이 방법은 다양한 분야에서 많이 사용이 되는데, Collaborative Filtering 추천 시스템 또한
# 이를 사용하면 쉽게 구현이 가능합니다.
flights = flights.pivot("month", "year", "passengers")
flights.head(5)
year
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
month
January
112
115
145
171
196
204
242
284
315
340
360
417
February
118
126
150
180
196
188
233
277
301
318
342
391
March
132
141
178
193
236
235
267
317
356
362
406
419
April
129
135
163
181
235
227
269
313
348
348
396
461
May
121
125
172
183
229
234
270
318
355
363
420
472
plt.figure(figsize=(10,8))
# sns.heatmap() 에 자주 들어가는 것은 피벗 테이블 한 결과입니다.
# 위의 피벗 테이블 결과를 히트맵 방식으로 시각화 하였습니다.
sns.heatmap(flights)
plt.show()
plt.figure(figsize=(10,8))
# sns.heatmap document:
# fmt 란?
# String formatting code to use when adding annotations.
# d 는 decimal(10진수) 이라는 것입니다.
# annot 란?
# If True, write the data value in each cell.
# If an array-like with the same shape as data,
# then use this to annotate the heatmap instead of the raw data.
# 각 네모의 안에 네모에 해당하는 값을 적어주는 옵션입니다.
sns.heatmap(flights, annot=True, fmt="d")
plt.show()
# 모든 컬럼들에 대해 산점도 행렬을 그려주는 기능입니다.
# 각 컬럼들 간의 상호 상관관계를 확인할 수 있습니다.
sns.pairplot(iris)
plt.show()
# hue 옵션으로 nominal variable 을 하나 더 추가해서
# 한 차원을 더 넣어 시각화 합니다.
sns.pairplot(iris, hue="species")
plt.show()
# 데이터 크기가 큰 경우, pairplot 시 시간이 너무 오래 걸리는 경우가 있습니다.
# 이럴 때는, 보고자 하는 컬럼들만 선택해 집어넣어서 해결할 수 있습니다.
sns.pairplot(iris, vars=["sepal_width", "sepal_length"])
plt.show()
# x 축과 y 축을 따로따로 지정해 산점도 행렬을 구할 수도 있습니다.
# 기존에는, 대각행렬 성분이 자기 자신과의 비교이기 때문에 값의 분포를 나타내는 정보이었는데
# 지금은 대각행렬 성분이 자기 자신과의 비교가 아니게 됩니다.
sns.pairplot(iris, x_vars=["sepal_width", "sepal_length"],
y_vars=["petal_width", "petal_length"])
plt.show()
# anscombe 데이터 셋을 불러와 향후 anscombe 라는 변수로 사용하기로 합니다.
anscombe = sns.load_dataset("anscombe")
anscombe.head(5)
dataset
x
y
0
I
10.0
8.04
1
I
8.0
6.95
2
I
13.0
7.58
3
I
9.0
8.81
4
I
11.0
8.33
sns.set_style("darkgrid")
# 여기에서는 ci(Confidence Interval) 을 None 으로 설정함으로서,
# 신뢰구간을 의도적으로 지워서 표현한 코드입니다.
sns.lmplot(x="x", y="y", data=anscombe.query("dataset == 'I'"), ci=None, size=7)
plt.show()
# scatter_kws 는 산점도를 그릴 때 점의 모양과 크기를 넣어주는 옵션입니다.
sns.lmplot(x="x", y="y", data=anscombe.query("dataset == 'I'"),
ci=None, scatter_kws={"s": 80}, size=7)
plt.show()
# 이번 데이터는 선형관계가 아닌 curvilinear 관계일 경우를 나타냅니다.
# 따라서, 선형회귀를 할 수 없음을 보여주고 있습니다.
sns.lmplot(x="x", y="y", data=anscombe.query("dataset == 'II'"),
order=1, ci=None, scatter_kws={"s": 80}, size=7)
plt.show()
# order 옵션을 통해 2차 함수로 fitting 한 코드입니다.
# 일반 1차함수 fitting 이 기본값이었고, 이를 옵션을 통해 2로 바꾼 모습입니다.
sns.lmplot(x="x", y="y", data=anscombe.query("dataset == 'II'"),
order=2, ci=None, scatter_kws={"s": 80}, size=7)
plt.show()
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
import platform
# matplotlib 은 기본적으로 영어이고, 한글 정보가 들어가면
# 폰트가 깨지기 때문에 matplotlib 의
# font_manager 와 rc 를 불러와 폰트를 설정하는 코드입니다.
path = "c:/Windows/Fonts/malgun.ttf"
from matplotlib import font_manager, rc
if platform.system() == 'Darwin':
rc('font', family='AppleGothic')
elif platform.system() == 'Windows':
font_name = font_manager.FontProperties(fname=path).get_name()
rc('font', family=font_name)
else:
print('Unknown system... sorry~~~~')
crime_anal_norm.head()
강간
강도
살인
절도
폭력
강간검거율
강도검거율
살인검거율
절도검거율
폭력검거율
인구수
CCTV
범죄
검거
구별
강남구
1.000000
0.941176
0.916667
0.953472
0.661386
77.728285
85.714286
76.923077
42.857143
86.484594
570500.0
2780
4.472701
369.707384
강동구
0.155620
0.058824
0.166667
0.445775
0.289667
78.846154
100.000000
75.000000
33.347422
82.890855
453233.0
773
1.116551
370.084431
강북구
0.146974
0.529412
0.416667
0.126924
0.274769
82.352941
92.857143
100.000000
43.096234
88.637222
330192.0
748
1.494746
406.943540
관악구
0.628242
0.411765
0.583333
0.562094
0.428234
69.062500
100.000000
88.888889
30.561715
80.109157
525515.0
1496
2.613667
368.622261
광진구
0.397695
0.529412
0.166667
0.671570
0.269094
91.666667
100.000000
100.000000
42.200925
83.047619
372164.0
707
2.034438
416.915211
# 강도, 살인, 폭력에 대해 산점도 행렬을 구하는 코드입니다.
# kind='reg' 는 regression line 을 그리겠다는 옵션입니다.
sns.pairplot(crime_anal_norm, vars=["강도", "살인", "폭력"], kind='reg', size=3)
plt.show()
C:\Users\one\AppData\Local\Continuum\anaconda3\lib\site-packages\seaborn\axisgrid.py:2065: UserWarning: The `size` parameter has been renamed to `height`; pleaes update your code.
warnings.warn(msg, UserWarning)
C:\Users\one\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\backends\backend_agg.py:211: RuntimeWarning: Glyph 8722 missing from current font.
font.set_text(s, 0.0, flags=flags)
C:\Users\one\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\backends\backend_agg.py:180: RuntimeWarning: Glyph 8722 missing from current font.
font.set_text(s, 0, flags=flags)
# x 축과 y 축에 대해 따로따로 값을 넣어서
# 산점도 행렬을 구합니다.
# 대각행렬 성분이 위와는 다름을 알 수 있습니다.
sns.pairplot(crime_anal_norm, x_vars=["인구수", "CCTV"],
y_vars=["살인", "강도"], kind='reg', size=3)
plt.show()
# 검거 라는 컬럼은 애초에 모든 범죄에 대해 더하기를 해서 얻은 지표입니다.
# 이는 정규화가 이루어지지 않았기 때문에 이 최대치를 100 으로 바꿔주는 코드입니다.
tmp_max = crime_anal_norm['검거'].max()
crime_anal_norm['검거'] = crime_anal_norm['검거'] / tmp_max * 100
crime_anal_norm_sort = crime_anal_norm.sort_values(by='검거', ascending=False)
crime_anal_norm_sort.head()
강간
강도
살인
절도
폭력
강간검거율
강도검거율
살인검거율
절도검거율
폭력검거율
인구수
CCTV
범죄
검거
구별
도봉구
0.000000
0.235294
0.083333
0.000000
0.000000
100.000000
100.0
100.0
44.967074
87.626093
348646.0
485
0.318627
100.000000
금천구
0.141210
0.058824
0.083333
0.172426
0.134074
80.794702
100.0
100.0
56.668794
86.465433
255082.0
1015
0.589867
97.997139
광진구
0.397695
0.529412
0.166667
0.671570
0.269094
91.666667
100.0
100.0
42.200925
83.047619
372164.0
707
2.034438
96.375820
동대문구
0.204611
0.470588
0.250000
0.314061
0.250887
84.393064
100.0
100.0
41.090358
87.401884
369496.0
1294
1.490147
95.444250
용산구
0.265130
0.529412
0.250000
0.169004
0.133128
89.175258
100.0
100.0
37.700706
83.121951
244203.0
1624
1.346674
94.776790
target_col = ['강간검거율', '강도검거율', '살인검거율', '절도검거율', '폭력검거율']
crime_anal_norm_sort = crime_anal_norm.sort_values(by='검거', ascending=False)
plt.figure(figsize = (10,10))
# cmap 이라는 옵션은 컬러 맵인데, 가장 큰 값과 가장 작은 값에 어떤 색을 대입할 지 결정합니다.
sns.heatmap(crime_anal_norm_sort[target_col], annot=True, fmt='f',
linewidths=.5, cmap='RdPu')
plt.title('범죄 검거 비율 (정규화된 검거의 합으로 정렬)')
plt.show()
target_col = ['강간', '강도', '살인', '절도', '폭력', '범죄']
# 여기서 5 로 나눠준 이유는 범죄의 종류가 5 가지 이기 때문입니다.
crime_anal_norm['범죄'] = crime_anal_norm['범죄'] / 5
crime_anal_norm_sort = crime_anal_norm.sort_values(by='범죄', ascending=False)
plt.figure(figsize = (10,10))
sns.heatmap(crime_anal_norm_sort[target_col], annot=True, fmt='f', linewidths=.5,
cmap='RdPu')
plt.title('범죄비율 (정규화된 발생 건수로 정렬)')
plt.show()
# to_csv 를 이용하여 데이터를 csv 파일로 저장해 줍니다.
crime_anal_norm.to_csv('../data/02. crime_in_Seoul_final.csv', sep=',',
encoding='utf-8')
Folium
import folium
# 파이썬에서 지도 시각화 도구인 folium 을 불러옵니다.
# folium 에는 Map 이라는 도구가 있는데, 여기에 위도/경도를 넣어주면
# 해당 좌표의 지도를 가져와 보여줍니다.
map_osm = folium.Map(location=[45.5236, -122.6750])
map_osm
# zoom_start 라는 옵션으로 지도의 확대 / 축소가 가능합니다.
stamen = folium.Map(location=[45.5236, -122.6750], zoom_start=13)
stamen
map_1 = folium.Map(location=[45.372, -121.6972], zoom_start=12,
tiles='Stamen Terrain')
# 해당 지도에 마코를 표시하는 기능입니다.
# popup 은 마우스와 interaction 시 필요한 정보입니다.
# icon 은 어떤 아이콘을 사용할지 입니다.
# .addto() 함수를 이용해 어떤 지도에 넣을지를 설정합니다.
folium.Marker([45.3288, -121.6625], popup='Mt. Hood Meadows',
icon=folium.Icon(icon='cloud')).add_to(map_1)
folium.Marker([45.3311, -121.7113], popup='Timberline Lodge',
icon=folium.Icon(icon='cloud')).add_to(map_1)
map_1
map_2 = folium.Map(location=[45.5236, -122.6750], tiles='Stamen Toner',
zoom_start=13)
folium.Marker([45.5244, -122.6699], popup='The Waterfront' ).add_to(map_2)
# circleMarker 는 지역을 원으로 표기하는 기능을 수행합니다.
folium.CircleMarker([45.5215, -122.6261], radius=50,
popup='Laurelhurst Park', color='#3186cc',
fill_color='#3186cc', ).add_to(map_2)
map_2
map_5 = folium.Map(location=[45.5236, -122.6750], zoom_start=13)
# 원이 아니라 n각형 마커도 만들 수 있습니다.
# n각형을 결정하는 옵션은 number_of_sides 입니다.
folium.RegularPolygonMarker([45.5012, -122.6655],
popup='Ross Island Bridge', fill_color='#132b5e',
number_of_sides=3, radius=10).add_to(map_5)
folium.RegularPolygonMarker([45.5132, -122.6708],
popup='Hawthorne Bridge', fill_color='#45647d',
number_of_sides=4, radius=10).add_to(map_5)
folium.RegularPolygonMarker([45.5275, -122.6692],
popup='Steel Bridge', fill_color='#769d96',
number_of_sides=6, radius=10).add_to(map_5)
folium.RegularPolygonMarker([45.5318, -122.6745],
popup='Broadway Bridge', fill_color='#769d96',
number_of_sides=8, radius=10).add_to(map_5)
map_5
import folium
import pandas as pd
# 미국의 실업률 정보가 있는 데이터 세트의 경로를 상대경로 방식으로 가져옵니다.
state_unemployment = '../data/02. folium_US_Unemployment_Oct2012.csv'
# 미국의 실업률 정보를 가져와 state_unimployment 변수에 집어넣습니다.
state_data = pd.read_csv(state_unemployment)
state_data.head()
State
Unemployment
0
AL
7.1
1
AK
6.8
2
AZ
8.1
3
AR
7.2
4
CA
10.1
# 미국 지역정보가 있는 json(딕셔너리와 동일합니다.) 경로를 상대경로 방식으로 가져옵니다.
state_geo = '../data/02. folium_us-states.json'
# 위도/경도가 40, 98인 곳의 지도를 가져와 zoom 은 4로 놓고 map 변수에 집어넣습니다.
map = folium.Map(location=[40, -98], zoom_start=4)
# 지도에 구역정보인 state_geo 를 넣고
# 구역별 실업률 정보인 state_data 를 넣어줍니다.
# 여기에서 사용할 데이터는 state_data 에서의 State 와 Unimployment 컬럼 입니다.
# key_on 은 두 데이터 셋을 join 할 때 사용 할 key 입니다.
# fill_color 는 어떤 색깔로 경/중을 표기할 지를 결정합니다.
map.choropleth(geo_data=state_geo, data=state_data,
columns=['State', 'Unemployment'],
key_on='feature.id',
fill_color='YlGn',
legend_name='Unemployment Rate (%)')
map
C:\Users\one\AppData\Local\Continuum\anaconda3\lib\site-packages\folium\folium.py:415: FutureWarning: The choropleth method has been deprecated. Instead use the new Choropleth class, which has the same arguments. See the example notebook 'GeoJSON_and_choropleth' for how to do this.
FutureWarning
범죄율에 대한 지도 시각화
import json
# 우리나라의 구역정보가 들어있는 geo-json 데이터의 상대경로를 지정합니다.
geo_path = '../data/02. skorea_municipalities_geo_simple.json'
# json 파일을 불러와 딕셔너리로 사용하기 위해 json.load() 를 사용합니다.
# 이 이유는 json 은 딕셔너리와 동일하게 생겼지만, 문자열로 저장되어 있기 때문입니다.
geo_str = json.load(open(geo_path, encoding='utf-8'))