DV 6주차

pandas
Author

김보람

Published

October 12, 2022

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

lambda, mpa($$)

lambda

- 예제1: 람다표현식 (lambda expression) 자체가 하나의 오브젝트임

(lambda x: (x-2)**2)  # lambda가 실행되는 순간 메모리상에 함수 오브젝트가 저장됨
<function __main__.<lambda>(x)>
  • lambda x: (x-2)**2\(lambda(x)=(x-2)^2\) 의 느낌으로 기억하면 쉬움

(사용방법)

(lambda x: (x-2)**2)(2)  # 입력 2-> 출력 (2-2)^2 = 0
0
(lambda x: (x-2)**2)(4)  # 입력 4-> 출력 (4-2)^2 = 4
4

- 예제2: 람다표현식에 이름을 줄 수 있음

f = lambda x: (x-2)**2
f(2),f(4)
(0, 4)

위의 코드는 아래와 같다

def f(x):
    return (x-2)**2
f(2), f(4)
(0, 4)

- 예제3: 조건부 출력

f = lambda x,y: x if x>y else y  # 큰 값 리턴
f(1,2),  f(-4,3)
(2, 3)

- 예제4: 람다표현식들의 리스트

fl = [lambda x: x, lambda x: x**2, lambda x: x**3]
type(fl)
list
fl[0](10), fl[1](10), fl[2](10)
(10, 100, 1000)
for f in fl:
    print(f(2))
2
4
8
for s in ['a','b','c']:
    print(s)
a
b
c
for s in ['a', lambda x:x, 'c']:
    print(s)
a
<function <lambda> at 0x7f3ddff33c20>
c
x = np.linspace(-1,1,100)
for f in fl:
    plt.plot(x,f(x),'--')

- 예제5: 람다표현식들의 딕셔너리

fd = {'f1': lambda x:x, 'f2': lambda x: x**2, 'f3':lambda x:x**3}
fd
{'f1': <function __main__.<lambda>(x)>,
 'f2': <function __main__.<lambda>(x)>,
 'f3': <function __main__.<lambda>(x)>}
for k in fd:
    plt.plot(x,fd[k](x),'--')

- 예제6: 람다표현식을 리턴하는 함수(함수를 리턴하는 함수)

(예비학습) 함수 \(g(x)\)가 정의되어 있을때 \(\frac{d}{dx}g(x)\)의 값을 계산

g = lambda x : x**2
g(3)
9

\(f'(x)\approx \frac{f(x+h)-f(x)}{h}\)

gg =  lambda x: (g(x+0.001)-g(x))/0.001
gg(3)
6.000999999999479

(예비학습끝)

(목표) 도함수를 구해주는 derivate 함수를 정의. 임의의 함수 g를 입력으로 받으면, g의 도함수 (gg)가 리턴되는 기능을 가진다.

def derivate(g):
    gg = lambda x: (g(x+0.001)-g(x))/0.001
    return gg

(사용)

g = lambda x: np.sin(x)
gg = derivate(g)
x = np.linspace(0,6.28,1000)
plt.plot(x,g(x))
plt.plot(x,gg(x))

(사용2)

g0 = lambda x: (1/6)*x**3
g1 = derivate(g0) # (1/2)x^2
g2 = derivate(g1) # x 
x = np.linspace(-1,1,100)
plt.plot(x,g0(x))
plt.plot(x,g1(x))
plt.plot(x,g2(x))

- 예제7: 예제6의 다른표현

derivate = lambda g : lambda x: (g(x+0.001)-g(x))/0.001
# 위와 같은 코드
g = lambda x: np.sin(x)
gg = derivate(g)
x = np.linspace(0,6.28,1000)
plt.plot(x,g(x))
plt.plot(x,gg(x))

(사용2)

g0 = lambda x: (1/6)*x**3
g1 = derivate(g0) # (1/2)x^2
g2 = derivate(g1) # x 
x = np.linspace(-1,1,100)
plt.plot(x,g0(x))
plt.plot(x,g1(x))
plt.plot(x,g2(x))

map

- 개념: \(\text{map}\left(f,[x_1,x_2,\dots,x_n] \right) = \left[f(x_1),f(x_2),\dots,f(x_n)\right]\)

- 예제1

x=[1,2,3]
f = lambda x: x+1
y= list(map(f,x))
list(map(f,x))
[2, 3, 4]
f(x) # 리스트라 오류남
TypeError: can only concatenate list (not "int") to list
f(x[0])
2

(다른구현1)

list(map(lambda x:x+1, x))
[2, 3, 4]
list(map(lambda x:x+1, [1,2,3]))
[2, 3, 4]

(다른구현2)

f = lambda x: x+1
[xi for xi in [1,2,3]]
[1, 2, 3]
f = lambda x: x+1
[f(xi) for xi in [1,2,3]]
[2, 3, 4]

(다른구현3)

[(lambda x:x+1)(xi) for xi in [1,2,3]]
[2, 3, 4]

(다른구현4)-최악

y = []
x = [1,2,3]
f = lambda x: x+1
for xi in x:
    y.append(f(xi))
y
[2, 3, 4]

(다른구현5)-더 최악

y = []
x = [1,2,3]
f = lambda x: x+1
for i in range(len(x)):
    y.append(f(x[i]))
y
[2, 3, 4]

- 예제2: 문자열을 입력으로 받고 대문자이면 True, 소문자이면 False

입력: A,B,C,a,b,c
출력: T,T,T,F,F,F
f(np.array(x))
array([2, 3, 4])
'A'.isupper()
True
#x = ['A', 'B', 'C', 'a', 'b', 'c']
x = list('ABCabc')
f = lambda s : s.isupper()
y = list(map(f,x))
x,y
(['A', 'B', 'C', 'a', 'b', 'c'], [True, True, True, False, False, False])

- 예제3: 두 개의 입력을 받는 함수

(lambda x,y : x+y)(-1,3)
2
list(map(lambda x,y: x+y, [1,2,3],[-1,-2,-3]))
[0, 0, 0]

(다른 구현) - 리스트컴프리헨션

f = lambda x,y: x+y
[f(x,y) for x,y in zip([1,2,3],[-1,-2,-3])]
[0, 0, 0]

- 예제4: map은 “하나의 함수에 다양한 입력”을 적용하는 경우에만 사용가능, 리스트 컴프리헨션은 “다양한 함수에 다양한 입력”을 지원한다.

flst = [lambda x: x+1, lambda x: x+2, lambda x: x+3]

(map으로 구현 시도) -> 실패

list(map(flst,[-1,-2,-3])) # 결과가 0,0,0 나오길 시도
TypeError: 'list' object is not callable

리스트컴프리헨션으로 구현시도 -> 성공

[f(x) for f,x in zip(flst, [-1,-2,-3])]
[0, 0, 0]

- 종합: map과 리스트컴프리헨션과 비교 - map은 반복인덱스를 쓰지 않지만 리스트컴프리헨션은 반복인덱스가 필요함 - map은 좀더 리스트컴프리헨션보다 제약적으로 사용할 수 밖에 없음

판다스: 인덱싱 공부 1단계: 인덱싱의 4가지 컨셉

데이터프레임 준비

df=pd.read_csv('https://raw.githubusercontent.com/guebin/DV2022/main/posts/dv2022.csv')
df
att rep mid fin
0 65 45 0 10
1 95 30 60 10
2 65 85 15 20
3 55 35 35 5
4 80 60 55 70
... ... ... ... ...
195 55 70 40 95
196 65 85 25 85
197 85 85 100 10
198 80 65 35 60
199 50 95 45 85

200 rows × 4 columns

- 앞으로는 위와 같은 df형태를 가정할 것이다. 즉 column의 이름은 문자열, row의 이름은 0부터 시작하는 정수로 가정한다.

np.array([[1,2,3],[1,2,5]])
array([[1, 2, 3],
       [1, 2, 5]])

- 아래와 같은 형태는 일단 생각 안함

pd.DataFrame({'att':[60,65,80,90],'rep':[50,100,90,100]},index=['A','B','C','D'])
att rep
A 60 50
B 65 100
C 80 90
D 90 100

df의 4가지 컨셉

- 원소에 접근하는 4가지 방법: ., [], iloc[], .loc[]

컨셉1: 클래스느낌

- 컨셉1: df는 인스턴스이다. 그리고 df.att, df.rep, df.mid, df.fin과 같이 col이름에 대응하는 속성이 있다.

df.head(6)
att rep mid fin
0 65 45 0 10
1 95 30 60 10
2 65 85 15 20
3 55 35 35 5
4 80 60 55 70
5 75 40 75 85
df.att
0      65
1      95
2      65
3      55
4      80
       ..
195    55
196    65
197    85
198    80
199    50
Name: att, Length: 200, dtype: int64
df.fin
0      10
1      10
2      20
3       5
4      70
       ..
195    95
196    85
197    10
198    60
199    85
Name: fin, Length: 200, dtype: int64

- 언제유용? col의 이름을 대충 알고 있을 경우 자동완성으로 쉽게 선택가능

컨셉2: 딕셔너리 + \(\alpha\) 느낌

- 컨셉2: df는 컬럼이름이 key, 컬럼의 데이터가 value가 되는 dictionary로 이해가능. 즉 아래의 dct와 같은 딕셔너리로 이해할 수 있다.

col indexing

- 예시1: dct가 가능하면 df도 가능하다.

dct = dict(df)
dct['att']
0      65
1      95
2      65
3      55
4      80
       ..
195    55
196    65
197    85
198    80
199    50
Name: att, Length: 200, dtype: int64
df['att']
0      65
1      95
2      65
3      55
4      80
       ..
195    55
196    65
197    85
198    80
199    50
Name: att, Length: 200, dtype: int64

- 예시2: dct가 가능하면 df도 가능하다.(2)

df.get('att')
#dct.get('att')
0      65
1      95
2      65
3      55
4      80
       ..
195    55
196    65
197    85
198    80
199    50
Name: att, Length: 200, dtype: int64

- 예시3: dct에서는 불가능하지만 df에서 가능한 것도 잇다.

dct.get('att')
0      65
1      95
2      65
3      55
4      80
       ..
195    55
196    65
197    85
198    80
199    50
Name: att, Length: 200, dtype: int64
dct.get(['att','rep']) #이건 안됨
TypeError: unhashable type: 'list'
df.get(['att','rep'])
att rep
0 65 45
1 95 30
2 65 85
3 55 35
4 80 60
... ... ...
195 55 70
196 65 85
197 85 85
198 80 65
199 50 95

200 rows × 2 columns

- 예시4: dct에서는 불가능하지만 df에서 가능한 것도 잇다.(2)

dct['att']
0      65
1      95
2      65
3      55
4      80
       ..
195    55
196    65
197    85
198    80
199    50
Name: att, Length: 200, dtype: int64
dct[['att','rep']]
TypeError: unhashable type: 'list'
df[['att','rep']]
att rep
0 65 45
1 95 30
2 65 85
3 55 35
4 80 60
... ... ...
195 55 70
196 65 85
197 85 85
198 80 65
199 50 95

200 rows × 2 columns

low indexing

- 예시5: dct에서는 불가능하지만 df에서 가능한 것도 잇다.(3)

dct[:5]
TypeError: unhashable type: 'slice'
df[:5]
att rep mid fin
0 65 45 0 10
1 95 30 60 10
2 65 85 15 20
3 55 35 35 5
4 80 60 55 70

컨셉3: 넘파이느낌

- 컨셉3: df.iloc은 넘파이어레이처럼 생각 가능하다. 즉 아래와 같은 넘파이 어레이로 생각 가능

arr=np.array(df)
arr
array([[ 65,  45,   0,  10],
       [ 95,  30,  60,  10],
       [ 65,  85,  15,  20],
       [ 55,  35,  35,   5],
       [ 80,  60,  55,  70],
       [ 75,  40,  75,  85],
       [ 65,  70,  60,  75],
       [ 60,  25,  20,  35],
       [ 95,  55,  65,  90],
       [ 90,  25,  95,  50],
       [ 55,  45,  75,  30],
       [ 95,  60,  25,  55],
       [ 95,  35,   0,  25],
       [ 50,  55,  90,  45],
       [ 50,  65,  50,  70],
       [ 95, 100,  25,  40],
       [ 50,  65,  35,  85],
       [ 65,  85,  10,   5],
       [ 70,  65,  65,  80],
       [ 90,  70, 100,  30],
       [ 80,  45,  80,  85],
       [ 55,  45,  85,  70],
       [ 65,  35,  45,  20],
       [ 70,  25,  50,  70],
       [ 85,  55,  30,  80],
       [ 90,  30,  30,   0],
       [100,  65,  50,  70],
       [ 80,  70,  50, 100],
       [ 80,  35,  25,  65],
       [ 55,  75,  20,  25],
       [ 75,  75,  85,  95],
       [ 80,  95,   5,   5],
       [ 95,  60,  65,  10],
       [ 95,  60,  90,  75],
       [100,  75,  70,  25],
       [100,  55,  35,  85],
       [ 80,  60,  65,  55],
       [ 70,  80,   0,  10],
       [ 85,  65,  60,  60],
       [100,  95,   0,  25],
       [ 95,  60,  15,  45],
       [ 75,  40,  30,  10],
       [ 70,  80,  50,  25],
       [ 50,  45,  10,  10],
       [100, 100, 100,  50],
       [ 75,  50,  60,   5],
       [ 85,  50,  35, 100],
       [ 80,  35,  75,  80],
       [ 95,  45,  35,  80],
       [ 65,  85,  85,  15],
       [ 90,  30,  25,   5],
       [ 65,  65,  35,  70],
       [ 80,  65,  30,  90],
       [ 95,  80,  45,  35],
       [ 65,  75,  50,  35],
       [ 90,  55, 100,  30],
       [ 95,  25,  95,  90],
       [100,  50,  80,  10],
       [ 50,  55,  35,  60],
       [ 90,  70,  35,  25],
       [ 50,  55,  15,  75],
       [ 80,  50,  55,  90],
       [ 50,  75,  65,  90],
       [ 70,  40,  90,   5],
       [ 65,  85,  20,  90],
       [ 60,  30,   0,  50],
       [ 50,  65,  15,   0],
       [ 60,  95,  30,  70],
       [ 70,  70,   5,   0],
       [ 75,  45,  15,  75],
       [ 50,  60,  15,  50],
       [ 85,  90,  90,  90],
       [ 80,  25,  85,  20],
       [ 55,  75,  95,  90],
       [ 85,  30,  45,  15],
       [ 65,  30,  45,  15],
       [ 85,  95,  35,  25],
       [ 60,  25,  10,  50],
       [ 95,  45,  90,  35],
       [ 85,  50,  60,  45],
       [ 60,  50, 100,  70],
       [100,  75,  60,   0],
       [100,  90,  85,  75],
       [ 55, 100, 100,  60],
       [ 70,  60,  30,  40],
       [ 70,  90,  95,  40],
       [ 55,  50,   0,   5],
       [100, 100,  45,  90],
       [ 85,  70,  90,  80],
       [100,  85,  65,  85],
       [ 60,  65,  35,  15],
       [ 65,  75,  75,  85],
       [ 65,  25,  40,   0],
       [ 75,  75,  50,  40],
       [ 50,  55,  80,  55],
       [ 75,  30,  20,  50],
       [100,  50,  25,  65],
       [ 90,  30,  95,  35],
       [ 55, 100,  80,   0],
       [ 75,  60,  15,  40],
       [ 60,  25,  25,  50],
       [ 85,  35,  10,  60],
       [ 60, 100,  55,  40],
       [ 70,  55,  50,  75],
       [ 80,  65,  95,  85],
       [ 65,  35,  15,  65],
       [ 85,  70, 100,   0],
       [100,  30,  60,  65],
       [ 65,  70,  55,  70],
       [ 85,  55,  85,  90],
       [ 85,  95,  80,  10],
       [ 85,  70,  75,   5],
       [100,  35,  70,   0],
       [ 95,  45,  55,  65],
       [ 95,  85,  40,  65],
       [ 55,  50,  30,  85],
       [ 85,  50,   5,  65],
       [ 75,  90,  85,  85],
       [ 95,  70,  10,   5],
       [ 85,  35,  80,  95],
       [ 95,  50,  80,  90],
       [100,  65,  75,  40],
       [ 95,  70,  70,   0],
       [ 95,  70,  20,  25],
       [100,  60,  10,   5],
       [ 55,  35,  25,  10],
       [ 60,  90,  40,   5],
       [ 85,  90,  85,  75],
       [ 75,  85,  25,  35],
       [ 55,  30,  50,  45],
       [ 70,  60,  75,  75],
       [ 80,  30,  95,   5],
       [ 90,  85,  80,  15],
       [ 90,  25,  95,   5],
       [ 60,  85,  50,  20],
       [ 90,  50,  95,  95],
       [ 75,  95,  65,  40],
       [ 60,  40,  35,   0],
       [ 55, 100,  15,  80],
       [ 70,  75,  80,   0],
       [ 75,  65,  25,  20],
       [ 90,  75,  80,  25],
       [ 50,  75,  75,  20],
       [ 55,  45,  35,  45],
       [ 90,  70,  90,   0],
       [ 75,  30, 100,  60],
       [ 90,  85,   0,  40],
       [ 85,  70,  35,   0],
       [100,  75, 100,  85],
       [ 55,  35,  20,  10],
       [ 70,  75,  90,  90],
       [ 90,  90,  55,  55],
       [ 55,  60,  40,   0],
       [100,  90,   5,  30],
       [ 50,  55,  25,  80],
       [100, 100,  90,  55],
       [ 70,  45,  70,  75],
       [ 85,  95,  85,  90],
       [ 55,  25,  95,  45],
       [ 75,  30,  10,  95],
       [ 65,  85,  15,  60],
       [ 70,  90,  70,   0],
       [ 60,  85,  70,  85],
       [100,  25,  10,  20],
       [ 75,  25,  80,  25],
       [ 90,  95,  40,  80],
       [ 95,  90,  50,  50],
       [ 90,  90,  65,  85],
       [ 95,  75,  50,  40],
       [ 55,  60,  70,   5],
       [ 95,  85,   0,  15],
       [ 65,  60,  35,  20],
       [ 65,  50,   5,   5],
       [ 90,  25,  60,  25],
       [100,  40,  40,  15],
       [ 70,  25, 100,  75],
       [100,  30,  70,  70],
       [ 50,  55,  55,   5],
       [ 70,  35,  70, 100],
       [ 70,  60,  60,  80],
       [ 55,  45,  90,   5],
       [ 55,  55,  10,  95],
       [ 65,  80,  10,  30],
       [ 90,  25,  35,  55],
       [100,  30,  30,  85],
       [ 70,  85,  70,  65],
       [ 60, 100,  45, 100],
       [ 70,  25, 100,  15],
       [ 70,  35,  80,  25],
       [ 65,  60,  30,  35],
       [ 95,  35,  40,  95],
       [ 50,  80,  65,  90],
       [100,  40,  80,  80],
       [ 55,  30,  95, 100],
       [ 65,  40,  65,  70],
       [ 55,  70,  40,  95],
       [ 65,  85,  25,  85],
       [ 85,  85, 100,  10],
       [ 80,  65,  35,  60],
       [ 50,  95,  45,  85]])

row indexing

- 예시1: 단일레이블

arr[0,:] # first row
array([65, 45,  0, 10])
arr[0]
array([65, 45,  0, 10])
arr[0,] # R
array([65, 45,  0, 10])
df.iloc[0,:]
# df.iloc[0,]
# df.iloc[0]
att    65
rep    45
mid     0
fin    10
Name: 0, dtype: int64

- 예시2: 레이블의 리스트

arr[[0,1,2],:]  # 처음 3개의 row 선택
arr[[0,1,2],]
arr[[0,1,2]]
array([[65, 45,  0, 10],
       [95, 30, 60, 10],
       [65, 85, 15, 20]])
df.iloc[[0,1,2],:]  # 처음 3개의 row 선택
df.iloc[[0,1,2],]
df.iloc[[0,1,2]]
att rep mid fin
0 65 45 0 10
1 95 30 60 10
2 65 85 15 20

- 예시3: 슬라이싱

arr[0:3,:]  # 처음 3개의 row 선택, 끝점포함x
arr[0:3,]
arr[0:3]
array([[65, 45,  0, 10],
       [95, 30, 60, 10],
       [65, 85, 15, 20]])
df.iloc[0:3,:]  # 처음 3개의 row 선택
df.iloc[0:3,]
df.iloc[0:3]
att rep mid fin
0 65 45 0 10
1 95 30 60 10
2 65 85 15 20

col indexing

df.head()
att rep mid fin
0 65 45 0 10
1 95 30 60 10
2 65 85 15 20
3 55 35 35 5
4 80 60 55 70

- 예시1: 단일레이블

#df.iloc[:,0] # first column 
arr[:,0] # first column 
array([ 65,  95,  65,  55,  80,  75,  65,  60,  95,  90,  55,  95,  95,
        50,  50,  95,  50,  65,  70,  90,  80,  55,  65,  70,  85,  90,
       100,  80,  80,  55,  75,  80,  95,  95, 100, 100,  80,  70,  85,
       100,  95,  75,  70,  50, 100,  75,  85,  80,  95,  65,  90,  65,
        80,  95,  65,  90,  95, 100,  50,  90,  50,  80,  50,  70,  65,
        60,  50,  60,  70,  75,  50,  85,  80,  55,  85,  65,  85,  60,
        95,  85,  60, 100, 100,  55,  70,  70,  55, 100,  85, 100,  60,
        65,  65,  75,  50,  75, 100,  90,  55,  75,  60,  85,  60,  70,
        80,  65,  85, 100,  65,  85,  85,  85, 100,  95,  95,  55,  85,
        75,  95,  85,  95, 100,  95,  95, 100,  55,  60,  85,  75,  55,
        70,  80,  90,  90,  60,  90,  75,  60,  55,  70,  75,  90,  50,
        55,  90,  75,  90,  85, 100,  55,  70,  90,  55, 100,  50, 100,
        70,  85,  55,  75,  65,  70,  60, 100,  75,  90,  95,  90,  95,
        55,  95,  65,  65,  90, 100,  70, 100,  50,  70,  70,  55,  55,
        65,  90, 100,  70,  60,  70,  70,  65,  95,  50, 100,  55,  65,
        55,  65,  85,  80,  50])
df.iloc[:,0] # first column
0      65
1      95
2      65
3      55
4      80
       ..
195    55
196    65
197    85
198    80
199    50
Name: att, Length: 200, dtype: int64

- 예시2: 레이블의 리스트

#arr[:,[0,2]] # col1, col3 선택
df.iloc[:,[0,2]] # 처음 3개의 row선택
att mid
0 65 0
1 95 60
2 65 15
3 55 35
4 80 55
... ... ...
195 55 40
196 65 25
197 85 100
198 80 35
199 50 45

200 rows × 2 columns

- 예시3: 슬라이싱

df.iloc[:,0:3] # 처음 3개의 col선택, 끝점포함X
#arr[:,0:3]
att rep mid
0 65 45 0
1 95 30 60
2 65 85 15
3 55 35 35
4 80 60 55
... ... ... ...
195 55 70 40
196 65 85 25
197 85 85 100
198 80 65 35
199 50 95 45

200 rows × 3 columns

row+col indexing

df.iloc[:2,0:3] 
att rep mid
0 65 45 0
1 95 30 60
df.iloc[::2,0:3]
att rep mid
0 65 45 0
2 65 85 15
4 80 60 55
6 65 70 60
8 95 55 65
... ... ... ...
190 95 35 40
192 100 40 80
194 65 40 65
196 65 85 25
198 80 65 35

100 rows × 3 columns

컨셉4: 데이터프레임 느낌

- 컨셉4: df.loc새로운 느낌 (R에 익숙하면 dataframe 혹은 티블느낌이라고 보면 된다.)

  • R에서.. 교수님꺼 강의노트 참고

row indexing

- 예시1: 단일레이블

df.loc[0,:]   # 첫번째 row를 선택
df.loc[0,]
df.loc[0]
att    65
rep    45
mid     0
fin    10
Name: 0, dtype: int64

- 예시2: 레이블의 리스트

df.loc[[0,1,2],:]   # 처음 3개의 row를 선택
df.loc[[0,1,2],]
df.loc[[0,1,2]]
att rep mid fin
0 65 45 0 10
1 95 30 60 10
2 65 85 15 20

- 예시3: 슬라이싱(끝점포함 O!!)

df.loc[0:3,:]   # 처음 4개의 row를 선택
df.loc[0:3,]
df.loc[0:3]
att rep mid fin
0 65 45 0 10
1 95 30 60 10
2 65 85 15 20
3 55 35 35 5

col indexing

- 예시1: 단일레이블

df.loc[:,'att']
0      65
1      95
2      65
3      55
4      80
       ..
195    55
196    65
197    85
198    80
199    50
Name: att, Length: 200, dtype: int64

- 예시2: 레이블의 리스트

df.loc[:,['att','mid']]
att mid
0 65 0
1 95 60
2 65 15
3 55 35
4 80 55
... ... ...
195 55 40
196 65 25
197 85 100
198 80 35
199 50 45

200 rows × 2 columns

- 예시3: 슬라이싱 (끝점 포함 O)

df.loc[:,'att':'mid']   # R에서는 안됬었고 끝점 포함
att rep mid
0 65 45 0
1 95 30 60
2 65 85 15
3 55 35 35
4 80 60 55
... ... ... ...
195 55 70 40
196 65 85 25
197 85 85 100
198 80 65 35
199 50 95 45

200 rows × 3 columns

row+col indexing

df.loc[::-1,'att':'mid']   
att rep mid
199 50 95 45
198 80 65 35
197 85 85 100
196 65 85 25
195 55 70 40
... ... ... ...
4 80 60 55
3 55 35 35
2 65 85 15
1 95 30 60
0 65 45 0

200 rows × 3 columns

컨셉 1~4 정리

. [] .iloc .loc
row/단일레이블 X X O O
col/단일레이블 O O O O
row/레이블리스트 X X O O
col/레이블리스트 X O O O
row/슬라이싱 X O O O
col/슬라이싱 X X O O

- col 이름을 알아야하는 부담감

  • . : 앞글자만 대충 알아도 자동완성 가능

  • []: 정확한 col 이름을 알아야 함

  • .loc: 보통 정확한 col 이름을 알아야 하지만 슬라이싱 이용시 양 끝의 컬럼이름만 알면 무방

  • .iloc: 정확한 col 이름을 몰라도 번호로 인덱싱 가능

- 자주하는 실수

# df['att'] # 가능
# df.loc['att'] # 불가능
df.loc[:,'att'] # 가능
0      65
1      95
2      65
3      55
4      80
       ..
195    55
196    65
197    85
198    80
199    50
Name: att, Length: 200, dtype: int64

판다스: 인덱싱 공부 2단계: 필터링 (특정조건에 맞는 row를 선택)

df.head()
att rep mid fin
0 65 45 0 10
1 95 30 60 10
2 65 85 15 20
3 55 35 35 5
4 80 60 55 70

att > 90 and rep < 50

- 방법1: .query() 를 이용

df.query('att>90 and rep<50')
att rep mid fin
1 95 30 60 10
12 95 35 0 25
48 95 45 35 80
56 95 25 95 90
78 95 45 90 35
107 100 30 60 65
112 100 35 70 0
113 95 45 55 65
163 100 25 10 20
174 100 40 40 15
176 100 30 70 70
184 100 30 30 85
190 95 35 40 95
192 100 40 80 80
df.query('(att>90)&(rep<50)')
att rep mid fin
1 95 30 60 10
12 95 35 0 25
48 95 45 35 80
56 95 25 95 90
78 95 45 90 35
107 100 30 60 65
112 100 35 70 0
113 95 45 55 65
163 100 25 10 20
174 100 40 40 15
176 100 30 70 70
184 100 30 30 85
190 95 35 40 95
192 100 40 80 80
df.query('att>90 & rep<50') 
att rep mid fin
1 95 30 60 10
12 95 35 0 25
48 95 45 35 80
56 95 25 95 90
78 95 45 90 35
107 100 30 60 65
112 100 35 70 0
113 95 45 55 65
163 100 25 10 20
174 100 40 40 15
176 100 30 70 70
184 100 30 30 85
190 95 35 40 95
192 100 40 80 80

- 방법2:[], .iloc

df[(df.att > 90) & (df.rep < 50)]
att rep mid fin
1 95 30 60 10
12 95 35 0 25
48 95 45 35 80
56 95 25 95 90
78 95 45 90 35
107 100 30 60 65
112 100 35 70 0
113 95 45 55 65
163 100 25 10 20
174 100 40 40 15
176 100 30 70 70
184 100 30 30 85
190 95 35 40 95
192 100 40 80 80
df.iloc[(df.att > 90) & (df.rep < 50)] # 오류남.. ! 리스터ㅡ로 바꿔주기
NotImplementedError: iLocation based boolean indexing on an integer type is not available
df.iloc[list((df.att > 90) & (df.rep < 50))]
att rep mid fin
1 95 30 60 10
12 95 35 0 25
48 95 45 35 80
56 95 25 95 90
78 95 45 90 35
107 100 30 60 65
112 100 35 70 0
113 95 45 55 65
163 100 25 10 20
174 100 40 40 15
176 100 30 70 70
184 100 30 30 85
190 95 35 40 95
192 100 40 80 80

- 방법3: [], .iloc, .loc // map, lambda

df[list(map(lambda x,y: (x>90)&(y<50), df.att, df.rep))]
# df[map(lambda x,y: (x>90)&(y<50), df.att, df.rep)] # 이것은 불가능
att rep mid fin
1 95 30 60 10
12 95 35 0 25
48 95 45 35 80
56 95 25 95 90
78 95 45 90 35
107 100 30 60 65
112 100 35 70 0
113 95 45 55 65
163 100 25 10 20
174 100 40 40 15
176 100 30 70 70
184 100 30 30 85
190 95 35 40 95
192 100 40 80 80
df.iloc[list(map(lambda x,y: (x>90)&(y<50), df.att, df.rep))]
df.iloc[map(lambda x,y: (x>90)&(y<50), df.att, df.rep)]
att rep mid fin
1 95 30 60 10
12 95 35 0 25
48 95 45 35 80
56 95 25 95 90
78 95 45 90 35
107 100 30 60 65
112 100 35 70 0
113 95 45 55 65
163 100 25 10 20
174 100 40 40 15
176 100 30 70 70
184 100 30 30 85
190 95 35 40 95
192 100 40 80 80
df.loc[list(map(lambda x,y: (x>90)&(y<50), df.att, df.rep))]
df.loc[map(lambda x,y: (x>90)&(y<50), df.att, df.rep)]
att rep mid fin
1 95 30 60 10
12 95 35 0 25
48 95 45 35 80
56 95 25 95 90
78 95 45 90 35
107 100 30 60 65
112 100 35 70 0
113 95 45 55 65
163 100 25 10 20
174 100 40 40 15
176 100 30 70 70
184 100 30 30 85
190 95 35 40 95
192 100 40 80 80

att > mean(att)

- 방법1: query

df.query('att> att.mean()') 
att rep mid fin
1 95 30 60 10
4 80 60 55 70
8 95 55 65 90
9 90 25 95 50
11 95 60 25 55
... ... ... ... ...
184 100 30 30 85
190 95 35 40 95
192 100 40 80 80
197 85 85 100 10
198 80 65 35 60

95 rows × 4 columns

- 방법2: []. .iloc, .loc

df[df.att > df.att.mean()]
df.loc[df.att > df.att.mean()]
df.iloc[list(df.att > df.att.mean())]
att rep mid fin
1 95 30 60 10
4 80 60 55 70
8 95 55 65 90
9 90 25 95 50
11 95 60 25 55
... ... ... ... ...
184 100 30 30 85
190 95 35 40 95
192 100 40 80 80
197 85 85 100 10
198 80 65 35 60

95 rows × 4 columns

- 방법3: [], .iloc, .loc // map, lambda

df[list(map(lambda x: x>df.att.mean() , df.att))]
# df[map(lambda x: x>df.att.mean() , df.att)] # 이것은 불가능
att rep mid fin
1 95 30 60 10
4 80 60 55 70
8 95 55 65 90
9 90 25 95 50
11 95 60 25 55
... ... ... ... ...
184 100 30 30 85
190 95 35 40 95
192 100 40 80 80
197 85 85 100 10
198 80 65 35 60

95 rows × 4 columns

df.iloc[list(map(lambda x: x>df.att.mean() , df.att))]
df.iloc[map(lambda x: x>df.att.mean() , df.att)]
att rep mid fin
1 95 30 60 10
4 80 60 55 70
8 95 55 65 90
9 90 25 95 50
11 95 60 25 55
... ... ... ... ...
184 100 30 30 85
190 95 35 40 95
192 100 40 80 80
197 85 85 100 10
198 80 65 35 60

95 rows × 4 columns

df.loc[list(map(lambda x: x>df.att.mean() , df.att))]
df.loc[map(lambda x: x>df.att.mean() , df.att)]
att rep mid fin
1 95 30 60 10
4 80 60 55 70
8 95 55 65 90
9 90 25 95 50
11 95 60 25 55
... ... ... ... ...
184 100 30 30 85
190 95 35 40 95
192 100 40 80 80
197 85 85 100 10
198 80 65 35 60

95 rows × 4 columns

요약

. [] .iloc .loc
row/단일레이블 X X O O
col/단일레이블 O O O O
row/레이블리스트 X X O O
col/레이블리스트 X O O O
row/슬라이싱 X O O O
col/슬라이싱 X X O O
row/bool,list X O O O
row/bool,ser X O X O
row/bool,map X X O O

숙제

숙제1

아래와 같이 0~9까지 포함된 리스트를 만들어라

x=list(range(10))
x
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

아래와 동일한 기능을 수행하는 함수를 lambda expression으로 정의하라.

def f(xi):
    return '짝' if (xi % 2)==0 else '홀'
ff = lambda x: "짝" if (x % 2)==0 else " 홀" 
ff(2)
'짝'
f(2)
'짝'

map과 lambda expression 을 이용하여 아래와 같은 결과를 만들어라. (리스트컴프리헨션, for문 사용금지)

x=list(range(10))
ff = lambda x: "짝" if (x % 2)==0 else " 홀" 
y=list(map(ff,x))
y
['짝', ' 홀', '짝', ' 홀', '짝', ' 홀', '짝', ' 홀', '짝', ' 홀']

숙제2

다음과 같은 데이터프레임을 불러온 뒤 물음에 답하라

df=pd.read_csv('https://raw.githubusercontent.com/guebin/DV2022/main/posts/dv2022.csv')
df
att rep mid fin
0 65 45 0 10
1 95 30 60 10
2 65 85 15 20
3 55 35 35 5
4 80 60 55 70
... ... ... ... ...
195 55 70 40 95
196 65 85 25 85
197 85 85 100 10
198 80 65 35 60
199 50 95 45 85

200 rows × 4 columns

(1) 기말고사 성적이 중간고사 성적보다 향상된 학생들을 출력하라. 즉 mid < fin 인 학생들을 출력하라. (다양한 방법으로 연습할 것, 제출은 한 가지 방법으로 구현해도 감점없음)

df.query('mid<fin')
att rep mid fin
0 65 45 0 10
2 65 85 15 20
4 80 60 55 70
5 75 40 75 85
6 65 70 60 75
... ... ... ... ...
194 65 40 65 70
195 55 70 40 95
196 65 85 25 85
198 80 65 35 60
199 50 95 45 85

93 rows × 4 columns

df.loc[(df.mid<df.fin)]
att rep mid fin
0 65 45 0 10
2 65 85 15 20
4 80 60 55 70
5 75 40 75 85
6 65 70 60 75
... ... ... ... ...
194 65 40 65 70
195 55 70 40 95
196 65 85 25 85
198 80 65 35 60
199 50 95 45 85

93 rows × 4 columns

df.iloc[list((df.mid<df.fin))]
att rep mid fin
0 65 45 0 10
2 65 85 15 20
4 80 60 55 70
5 75 40 75 85
6 65 70 60 75
... ... ... ... ...
194 65 40 65 70
195 55 70 40 95
196 65 85 25 85
198 80 65 35 60
199 50 95 45 85

93 rows × 4 columns

df[list(map(lambda x,y: x<y, df.mid, df.fin))]
att rep mid fin
0 65 45 0 10
2 65 85 15 20
4 80 60 55 70
5 75 40 75 85
6 65 70 60 75
... ... ... ... ...
194 65 40 65 70
195 55 70 40 95
196 65 85 25 85
198 80 65 35 60
199 50 95 45 85

93 rows × 4 columns

(2) 기말고사 성적이 중간고사 성적보다 향상된 학생들의 출석과 레포트 점수를 출력하라.

df2 = df.query('mid<fin').copy()
df2.head()
att rep mid fin
0 65 45 0 10
2 65 85 15 20
4 80 60 55 70
5 75 40 75 85
6 65 70 60 75
df2.loc[:,['att','rep']]
att rep
0 65 45
2 65 85
4 80 60
5 75 40
6 65 70
... ... ...
194 65 40
195 55 70
196 65 85
198 80 65
199 50 95

93 rows × 2 columns

  • df2로 받는 방법 말고 다른 방법이 또 있을 거 같은뎀,,