데이터 다루기
데이터 다루기
1. 학습 준비
1
!pip install --upgrade pip
1
2
# pandasql 라이브러리 설치
!pip3 install pandasql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 데이터와 라이브러리가 준비 되었다면 아래 코드로 데이터가 잘 불러지는지 확인해보자.
import os
import pandas as pd
from pandasql import sqldf
# pandasql을 전역 환경으로 지정
mysql = lambda q: sqldf(q, globals())
data_dir = 'C:/Users/daydr/data/sql_basic/'
bike = pd.read_csv(os.path.join(data_dir, 'bike_dataset.csv'))
orders = pd.read_csv(os.path.join(data_dir, 'orders.csv'))
customers = pd.read_csv(os.path.join(data_dir, 'customers.csv'))
employees = pd.read_csv(os.path.join(data_dir,'employees.csv'))
ds_2020 = pd.read_csv(os.path.join(data_dir, 'DS_JobsSalaries_2020.csv'))
ds_2021 = pd.read_csv(os.path.join(data_dir, 'DS_JobsSalaries_2021.csv'))
print("데이터 준비 완료!")
1
데이터 준비 완료!
2. 쿼리문 작성과 데이터 필터링
2-1. 쿼리문 작성하기(SELECT, FROM)
전체 컬럼 조회하기
SELECT구문에*기호를 사용하면 해당 테이블의 모든 컬럼을 조회할 수 있다.
1
2
SELECT *
FROM 테이블명
1
2
3
4
5
6
7
8
# bike 테이블에서 전체 컬럼을 조회해보자.
mysql("""
SELECT *
FROM bike
LIMIT 5;
""")
| dteday | season | yr | mnth | hr | holiday | weekday | workingday | weathersit | temp | atemp | hum | windspeed | casual | registered | cnt | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2011-01-01 | spring | 2011 | Jan | 0 | 0 | Saturday | 0 | Clear | 0.24 | 0.2879 | 0.81 | 0.0 | 3 | 13 | 16 |
| 1 | 2011-01-01 | spring | 2011 | Jan | 1 | 0 | Saturday | 0 | Clear | 0.22 | 0.2727 | 0.80 | 0.0 | 8 | 32 | 40 |
| 2 | 2011-01-01 | spring | 2011 | Jan | 2 | 0 | Saturday | 0 | Clear | 0.22 | 0.2727 | 0.80 | 0.0 | 5 | 27 | 32 |
| 3 | 2011-01-01 | spring | 2011 | Jan | 3 | 0 | Saturday | 0 | Clear | 0.24 | 0.2879 | 0.75 | 0.0 | 3 | 10 | 13 |
| 4 | 2011-01-01 | spring | 2011 | Jan | 4 | 0 | Saturday | 0 | Clear | 0.24 | 0.2879 | 0.75 | 0.0 | 0 | 1 | 1 |
2-2. 전체 데이터 필터링하기(WHERE)
WHERE는FROM절 다음에 위치WHERE절에는 연산자를 같이 사용해야함.
1
2
3
SELECT 원하는 컬럼
FROM 테이블명
WHERE 조건절
1
2
3
4
5
6
7
8
9
# 2012년을 기준으로 데이터를 확인해보자.
mysql("""
SELECT *
FROM bike
WHERE yr = 2012
LIMIT 5;
""")
| dteday | season | yr | mnth | hr | holiday | weekday | workingday | weathersit | temp | atemp | hum | windspeed | casual | registered | cnt | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2012-01-01 | spring | 2012 | Jan | 0 | 0 | Sunday | 0 | Clear | 0.36 | 0.3788 | 0.66 | 0.0000 | 5 | 43 | 48 |
| 1 | 2012-01-01 | spring | 2012 | Jan | 1 | 0 | Sunday | 0 | Clear | 0.36 | 0.3485 | 0.66 | 0.1343 | 15 | 78 | 93 |
| 2 | 2012-01-01 | spring | 2012 | Jan | 2 | 0 | Sunday | 0 | Clear | 0.32 | 0.3485 | 0.76 | 0.0000 | 16 | 59 | 75 |
| 3 | 2012-01-01 | spring | 2012 | Jan | 3 | 0 | Sunday | 0 | Clear | 0.30 | 0.3333 | 0.81 | 0.0000 | 11 | 41 | 52 |
| 4 | 2012-01-01 | spring | 2012 | Jan | 4 | 0 | Sunday | 0 | Clear | 0.28 | 0.3030 | 0.81 | 0.0896 | 0 | 8 | 8 |
3. 비교 연산자 사용하기
3-1. 비교 연산자
| 연산자 | 의미 |
|---|---|
| = | 같다 |
| !=, <> | 같지 않다 |
| > | 크다 |
| >= | 크거나 같다 |
| < | 작다 |
| <= | 작거나 같다 |
!= 또는 <> 는 ‘같지 않다’라는 뜻. 특정 데이터를 제외하여 선택할 때 사용함.
1
2
3
4
5
6
7
# 계절이 봄이 아닌 전체 데이터를 확인해보자.
mysql("""
SELECT *
FROM bike
WHERE season != 'spring'
""")
| dteday | season | yr | mnth | hr | holiday | weekday | workingday | weathersit | temp | atemp | hum | windspeed | casual | registered | cnt | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2011-03-21 | summer | 2011 | Mar | 0 | 0 | Monday | 1 | LightRain | 0.34 | 0.3030 | 0.66 | 0.3881 | 2 | 11 | 13 |
| 1 | 2011-03-21 | summer | 2011 | Mar | 1 | 0 | Monday | 1 | Cloudy | 0.34 | 0.3030 | 0.71 | 0.3881 | 1 | 6 | 7 |
| 2 | 2011-03-21 | summer | 2011 | Mar | 2 | 0 | Monday | 1 | Cloudy | 0.34 | 0.3030 | 0.71 | 0.3284 | 1 | 5 | 6 |
| 3 | 2011-03-21 | summer | 2011 | Mar | 3 | 0 | Monday | 1 | Cloudy | 0.34 | 0.3030 | 0.71 | 0.3284 | 0 | 1 | 1 |
| 4 | 2011-03-21 | summer | 2011 | Mar | 5 | 0 | Monday | 1 | Clear | 0.32 | 0.3030 | 0.81 | 0.2985 | 1 | 1 | 2 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 13132 | 2012-12-20 | winter | 2012 | Dec | 19 | 0 | Thursday | 1 | LightRain | 0.34 | 0.3182 | 0.71 | 0.2537 | 3 | 115 | 118 |
| 13133 | 2012-12-20 | winter | 2012 | Dec | 20 | 0 | Thursday | 1 | LightRain | 0.34 | 0.3333 | 0.76 | 0.1642 | 1 | 49 | 50 |
| 13134 | 2012-12-20 | winter | 2012 | Dec | 21 | 0 | Thursday | 1 | LightRain | 0.34 | 0.3333 | 0.76 | 0.1642 | 1 | 25 | 26 |
| 13135 | 2012-12-20 | winter | 2012 | Dec | 22 | 0 | Thursday | 1 | LightRain | 0.34 | 0.3333 | 0.87 | 0.1940 | 1 | 20 | 21 |
| 13136 | 2012-12-20 | winter | 2012 | Dec | 23 | 0 | Thursday | 1 | LightRain | 0.40 | 0.4091 | 0.82 | 0.2985 | 0 | 13 | 13 |
13137 rows × 16 columns
4. 논리 연산자 사용하기
- 여러가지 조건을 주고 싶을 때 사용
- 논리 연산자를 계속 추가하면 복잡한 조건도 쉽게 필터링 가능
| 연산자 | 의미 |
|---|---|
| AND | 앞의 조건과 뒤의 조건을 둘 다 만족해야 참 -> 여러개의 조건 존재 |
| OR | 앞의 조건이나 뒤의 조건 중 하나라도 만족해야 참 -> 여러개의 조건 존재 |
| IN | 여러개 값 리스트 중 하나의 값이라도 만족하는 해당 결과를 출력할 때 사용 |
| NOT | 논리 연산자의 의미를 반전시킴 -> 조건을 부정으로 만드는 역할 |
1
2
3
4
5
6
7
8
9
# bike 테이블에서 2011년도 데이터를 추출해 봅시다.
mysql("""
SELECT *
FROM bike
WHERE yr = 2011
LIMIT 5;
""")
| dteday | season | yr | mnth | hr | holiday | weekday | workingday | weathersit | temp | atemp | hum | windspeed | casual | registered | cnt | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2011-01-01 | spring | 2011 | Jan | 0 | 0 | Saturday | 0 | Clear | 0.24 | 0.2879 | 0.81 | 0.0 | 3 | 13 | 16 |
| 1 | 2011-01-01 | spring | 2011 | Jan | 1 | 0 | Saturday | 0 | Clear | 0.22 | 0.2727 | 0.80 | 0.0 | 8 | 32 | 40 |
| 2 | 2011-01-01 | spring | 2011 | Jan | 2 | 0 | Saturday | 0 | Clear | 0.22 | 0.2727 | 0.80 | 0.0 | 5 | 27 | 32 |
| 3 | 2011-01-01 | spring | 2011 | Jan | 3 | 0 | Saturday | 0 | Clear | 0.24 | 0.2879 | 0.75 | 0.0 | 3 | 10 | 13 |
| 4 | 2011-01-01 | spring | 2011 | Jan | 4 | 0 | Saturday | 0 | Clear | 0.24 | 0.2879 | 0.75 | 0.0 | 0 | 1 | 1 |
그렇다면 두가지의 조건을 주고 싶을때는 어떻게 해야할까?
4-1. AND
- 앞의 조건과 뒤의 조건 둘 다를 만족해야 참(True)이다.
- 조건을 계속 추가해야 할 때 사용
WHERE [조건1] AND [조건2]
1
2
3
4
5
6
7
8
9
10
11
# bike 테이블에서 2011년도 봄시즌의 22시에 발생한 데이터 추출
mysql("""
SELECT *
FROM bike
WHERE yr = 2011
AND season = 'spring'
AND hr = 22
LIMIT 5;
""")
| dteday | season | yr | mnth | hr | holiday | weekday | workingday | weathersit | temp | atemp | hum | windspeed | casual | registered | cnt | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2011-01-01 | spring | 2011 | Jan | 22 | 0 | Saturday | 0 | Cloudy | 0.40 | 0.4091 | 0.94 | 0.2239 | 11 | 17 | 28 |
| 1 | 2011-01-02 | spring | 2011 | Jan | 22 | 0 | Sunday | 0 | Clear | 0.24 | 0.2121 | 0.44 | 0.2985 | 0 | 9 | 9 |
| 2 | 2011-01-03 | spring | 2011 | Jan | 22 | 0 | Monday | 1 | Clear | 0.14 | 0.1515 | 0.69 | 0.1343 | 0 | 20 | 20 |
| 3 | 2011-01-04 | spring | 2011 | Jan | 22 | 0 | Tuesday | 1 | Clear | 0.22 | 0.2576 | 0.64 | 0.0896 | 1 | 34 | 35 |
| 4 | 2011-01-05 | spring | 2011 | Jan | 22 | 0 | Wednesday | 1 | Clear | 0.18 | 0.1970 | 0.55 | 0.1343 | 1 | 41 | 42 |
4-2. OR
- 앞의 조건을 만족하거나 뒤의 조건을 만족하거나, 한쪽이라도 만족해야 참(True)이다.
- 조건을 계속 추가해야 할 때 사용한다.
WHERE [조건1] OR [조건2]
1
2
3
4
5
6
7
8
9
10
# bike 테이블에서 2011년 또는 봄시즌의 데이터 추출
mysql("""
SELECT *
FROM bike
WHERE yr = 2011
OR season = 'spring'
LIMIT 5;
""")
| dteday | season | yr | mnth | hr | holiday | weekday | workingday | weathersit | temp | atemp | hum | windspeed | casual | registered | cnt | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2011-01-01 | spring | 2011 | Jan | 0 | 0 | Saturday | 0 | Clear | 0.24 | 0.2879 | 0.81 | 0.0 | 3 | 13 | 16 |
| 1 | 2011-01-01 | spring | 2011 | Jan | 1 | 0 | Saturday | 0 | Clear | 0.22 | 0.2727 | 0.80 | 0.0 | 8 | 32 | 40 |
| 2 | 2011-01-01 | spring | 2011 | Jan | 2 | 0 | Saturday | 0 | Clear | 0.22 | 0.2727 | 0.80 | 0.0 | 5 | 27 | 32 |
| 3 | 2011-01-01 | spring | 2011 | Jan | 3 | 0 | Saturday | 0 | Clear | 0.24 | 0.2879 | 0.75 | 0.0 | 3 | 10 | 13 |
| 4 | 2011-01-01 | spring | 2011 | Jan | 4 | 0 | Saturday | 0 | Clear | 0.24 | 0.2879 | 0.75 | 0.0 | 0 | 1 | 1 |
4-3. IN
- 컬럼이 어떤 값들의 집합에 속할 경우
IN을 사용 - 조회하고자 하는 데이터 값이 여러 개일 때 사용
- 데이터 값을 여러 개의 list로 지정할 수 있다.
1
2
3
4
5
6
7
8
9
# IN을 사용하여 1월(Jan), 3월(Mar), 5월(May)에 대한 전체 데이터 추출
mysql("""
SELECT *
FROM bike
WHERE mnth IN ('Jan', 'Mar', 'May')
LIMIT 5;
""")
| dteday | season | yr | mnth | hr | holiday | weekday | workingday | weathersit | temp | atemp | hum | windspeed | casual | registered | cnt | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2011-01-01 | spring | 2011 | Jan | 0 | 0 | Saturday | 0 | Clear | 0.24 | 0.2879 | 0.81 | 0.0 | 3 | 13 | 16 |
| 1 | 2011-01-01 | spring | 2011 | Jan | 1 | 0 | Saturday | 0 | Clear | 0.22 | 0.2727 | 0.80 | 0.0 | 8 | 32 | 40 |
| 2 | 2011-01-01 | spring | 2011 | Jan | 2 | 0 | Saturday | 0 | Clear | 0.22 | 0.2727 | 0.80 | 0.0 | 5 | 27 | 32 |
| 3 | 2011-01-01 | spring | 2011 | Jan | 3 | 0 | Saturday | 0 | Clear | 0.24 | 0.2879 | 0.75 | 0.0 | 3 | 10 | 13 |
| 4 | 2011-01-01 | spring | 2011 | Jan | 4 | 0 | Saturday | 0 | Clear | 0.24 | 0.2879 | 0.75 | 0.0 | 0 | 1 | 1 |
OR로도 동일한 데이터를 추출할 수 있지만 하나의 컬럼에서 같은 인자를 조건으로 줄 때IN을 사용하는 것이 효율적이다.
4-4. NOT
- 논리 연산자의 의미를 반전시킨다.
- 조건을 부정으로 만들어 부정 연산자라고도 불림
- 선언한 조건에 대해 반대 결과를 반환한다.
1
2
3
4
5
6
7
8
9
# 1월(Jan), 3월(Mar), 5월(May)이 아닌 전체 데이터 추출
mysql("""
SELECT *
FROM bike
WHERE mnth IN ('Jan', 'Mar', 'May')
LIMIT 5;
""")
| dteday | season | yr | mnth | hr | holiday | weekday | workingday | weathersit | temp | atemp | hum | windspeed | casual | registered | cnt | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2011-01-01 | spring | 2011 | Jan | 0 | 0 | Saturday | 0 | Clear | 0.24 | 0.2879 | 0.81 | 0.0 | 3 | 13 | 16 |
| 1 | 2011-01-01 | spring | 2011 | Jan | 1 | 0 | Saturday | 0 | Clear | 0.22 | 0.2727 | 0.80 | 0.0 | 8 | 32 | 40 |
| 2 | 2011-01-01 | spring | 2011 | Jan | 2 | 0 | Saturday | 0 | Clear | 0.22 | 0.2727 | 0.80 | 0.0 | 5 | 27 | 32 |
| 3 | 2011-01-01 | spring | 2011 | Jan | 3 | 0 | Saturday | 0 | Clear | 0.24 | 0.2879 | 0.75 | 0.0 | 3 | 10 | 13 |
| 4 | 2011-01-01 | spring | 2011 | Jan | 4 | 0 | Saturday | 0 | Clear | 0.24 | 0.2879 | 0.75 | 0.0 | 0 | 1 | 1 |
4-5. NULL
- 값이 지정되지 않아 알 수 없는 값
- NULL은 0이나 공백과는 다르다.
- 0 : 숫자
- ” “(공백) : 문자열
1
2
3
4
5
6
7
8
9
# 날씨 데이터의 값이 NULL값이 아닌 전체 데이터 추출
mysql("""
SELECT *
FROM bike
WHERE weathersit IS NOT NULL
LIMIT 5;
""")
| dteday | season | yr | mnth | hr | holiday | weekday | workingday | weathersit | temp | atemp | hum | windspeed | casual | registered | cnt | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2011-01-01 | spring | 2011 | Jan | 0 | 0 | Saturday | 0 | Clear | 0.24 | 0.2879 | 0.81 | 0.0 | 3 | 13 | 16 |
| 1 | 2011-01-01 | spring | 2011 | Jan | 1 | 0 | Saturday | 0 | Clear | 0.22 | 0.2727 | 0.80 | 0.0 | 8 | 32 | 40 |
| 2 | 2011-01-01 | spring | 2011 | Jan | 2 | 0 | Saturday | 0 | Clear | 0.22 | 0.2727 | 0.80 | 0.0 | 5 | 27 | 32 |
| 3 | 2011-01-01 | spring | 2011 | Jan | 3 | 0 | Saturday | 0 | Clear | 0.24 | 0.2879 | 0.75 | 0.0 | 3 | 10 | 13 |
| 4 | 2011-01-01 | spring | 2011 | Jan | 4 | 0 | Saturday | 0 | Clear | 0.24 | 0.2879 | 0.75 | 0.0 | 0 | 1 | 1 |
4-6. Between A and B
- A와 B 사이에 값이 존재할 때 사용.
- 주의할 점 : A와 B를 포함
- 두 값의 범우에 해당하는 행을 출력할 때 사용
- 주로 날짜 사이에 간격을 줄 때 자주 사용하는 편
- 최소값과 최대값을 지정한 값의 범위 내에 있는 값들을 검색하기 위해 사용
number Between 3 AND 5와number >= 3 AND number <= 5는 동일한 결과를 출력
1
2
3
4
5
6
7
8
9
10
# 2011년 3월 30일 ~ 31일 사이의 데이터를 확인해보자.
mysql("""
SELECT *
FROM bike
WHERE dteday >= '2011-03-30'
AND dteday <= '2011-03-31'
LIMIT 5;
""")
| dteday | season | yr | mnth | hr | holiday | weekday | workingday | weathersit | temp | atemp | hum | windspeed | casual | registered | cnt | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2011-03-30 | summer | 2011 | Mar | 0 | 0 | Wednesday | 1 | Cloudy | 0.32 | 0.3485 | 0.57 | 0.0 | 3 | 8 | 11 |
| 1 | 2011-03-30 | summer | 2011 | Mar | 1 | 0 | Wednesday | 1 | Clear | 0.32 | 0.3485 | 0.39 | 0.0 | 1 | 9 | 10 |
| 2 | 2011-03-30 | summer | 2011 | Mar | 2 | 0 | Wednesday | 1 | Cloudy | 0.32 | 0.3485 | 0.57 | 0.0 | 0 | 4 | 4 |
| 3 | 2011-03-30 | summer | 2011 | Mar | 3 | 0 | Wednesday | 1 | Cloudy | 0.32 | 0.3485 | 0.49 | 0.0 | 0 | 4 | 4 |
| 4 | 2011-03-30 | summer | 2011 | Mar | 4 | 0 | Wednesday | 1 | Cloudy | 0.32 | 0.3485 | 0.57 | 0.0 | 1 | 0 | 1 |
5. 산술 연산자 사용하기
- 데이터 값을 계산하고자 할 때 사용
- 산술연산자는
+,-,*,/등이 있다.- 우선순위
()>*,/>+,-
- 우선순위
SELECT,WHERE문에서 사용됨.
1
2
3
4
5
6
7
8
# dteday 값에 2를 더하고, weekday에 3을 더하면 어떻게 될까?
mysql("""
SELECT dteday, dteday + 2, weekday , weekday + 3
FROM bike
LIMIT 3;
""")
| dteday | dteday + 2 | weekday | weekday + 3 | |
|---|---|---|---|---|
| 0 | 2011-01-01 | 2013 | Saturday | 3 |
| 1 | 2011-01-01 | 2013 | Saturday | 3 |
| 2 | 2011-01-01 | 2013 | Saturday | 3 |
주의: 위의 코드는 DBMS(Database Management system)에 따라 실행했을 때 에러가 날 수 있기 때문에 날짜나 문자 타입의 경우에는 산술 연산자를 사용하지 않는 것이 좋다.
1
2
3
4
5
6
7
8
9
10
11
12
# 온도(temp)에 +2, -2, *2, /2 추가해보자.
mysql("""
SELECT temp
, temp + 2
, temp - 2
, temp * 2
, temp / 2
FROM bike
LIMIT 3;
""")
| temp | temp + 2 | temp - 2 | temp * 2 | temp / 2 | |
|---|---|---|---|---|---|
| 0 | 0.24 | 2.24 | -1.76 | 0.48 | 0.12 |
| 1 | 0.22 | 2.22 | -1.78 | 0.44 | 0.11 |
| 2 | 0.22 | 2.22 | -1.78 | 0.44 | 0.11 |
This post is licensed under CC BY 4.0 by the author.