import numpy as np
import matplotlib.pyplot as plt
import pandas as pdlambda, 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 = 00
(lambda x: (x-2)**2)(4) # 입력 4-> 출력 (4-2)^2 = 44
- 예제2: 람다표현식에 이름을 줄 수 있음
f = lambda x: (x-2)**2f(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),'--')_files/figure-html/cell-17-output-1.png)
- 예제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),'--')_files/figure-html/cell-19-output-1.png)
- 예제6: 람다표현식을 리턴하는 함수(함수를 리턴하는 함수)
(예비학습) 함수 \(g(x)\)가 정의되어 있을때 \(\frac{d}{dx}g(x)\)의 값을 계산
g = lambda x : x**2g(3)9
\(f'(x)\approx \frac{f(x+h)-f(x)}{h}\)
gg = lambda x: (g(x+0.001)-g(x))/0.001gg(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))_files/figure-html/cell-28-output-1.png)
(사용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))_files/figure-html/cell-31-output-1.png)
- 예제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))_files/figure-html/cell-36-output-1.png)
(사용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))_files/figure-html/cell-39-output-1.png)
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.att0 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.fin0 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)
arrarray([[ 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 rowarray([65, 45, 0, 10])
arr[0]array([65, 45, 0, 10])
arr[0,] # Rarray([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 column0 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로 받는 방법 말고 다른 방법이 또 있을 거 같은뎀,,