# [[[ 1 2 3],[ 4 5 6]]
# [[ 7 8 9], [10 11 12]]]
# 모양의 3차원 배열을 만드세요
print(np.arange(1, 13).reshape(2, 2, 3))
# mpg 데이터 불러오기
import pydataset
mpg_data = pydataset.data('mpg')
# mpg 데이터에서 'displ'을 4분위로 나누어라
mpg_data['displ'].quantile([0, 0.25, .50, .75, 1])
# 0.00 1.6
# 0.25 2.4
# 0.50 3.3
# 0.75 4.6
# 1.00 7.0
# Name: displ, dtype: float64
# 10초가 지나면 retire 가 출력되게 하세요
import time
def se(st) :
time.sleep(10)
print(st)
se('retire')
# 3초가 지나면 3에서 1씩 줄어드는 while 문을 작성하세요
i = 3
while i > 0 :
time.sleep(3)
print(i)
i -= 1
# diamonds 데이터 가져와 산점도를 그려라
# carat에 따른 price를 color별로
diamonds = pydataset.data('diamonds')
diamonds # 데이터 확인
import seaborn as sns
sns.scatterplot(data = diamonds, x = 'carat', y = 'price', hue='color')

# carat별 평균 구하기
diamonds.groupby(['carat']).mean()
# carat을 정수로 바꾼 후 평균 구하기
df = diamonds.copy()
df['carat'] = df['carat'].astype('int')
df = df.groupby(['carat']).mean()
df = df.reset_index()
# 캐럿별 변화에 따른 가격의 차이가 가장 큰 구간은?
# diff라는 열로 만드세요
df['diff'] = df['price'] - df['price'].shift()
# df['diff'] = df['price'].shift(1)
df
#[추가 답변]
df['diff'] = df.groupby(['carat']).mean().diff()['price']
df
# li 리스트로 딕셔너리 만들기
li = ['A', 'B', 'C']
d = {}
d1 = {}
for i, j in enumerate(li):
d[i] = j
d1[j] = i
print(d)
print(d1)
# {0: 'A', 1: 'B', 2: 'C'}
# {'A': 0, 'B': 1, 'C': 2}
# 컴프리핸션으로 만들기
d2 = {i:j for i, j in enumerate(li)}
d2
# {0: 'A', 1: 'B', 2: 'C'}
열거하다라는 뜻으로 순서가 있는 자료형(리스트, 튜플, 문자열)을 받아 인덱스 값을 포함하는 객체를 돌려준다.
(0908 - Python)
test = ["a", "b", "c"]
for i, j in enumerate(a) :
print(i, j)
>
0 a
1 b
2 c
# i가 인덱스 j가 값
간결한 표현으로 새로운 리스트를 만들 수 있다
li = [1, 2, 3, 4]
li_1 = []
for i in range(len(li)) :
li_1.append(i * 2)
print(li_1)
# [0, 2, 4, 6]
[i*2 for i in range(len(li))]
# [0, 2, 4, 6]
위와 아래는 결국 같은 결과값을 출력하는 코드이다. for 문으로 사용하여 계산결과가 담겨있는 새로운 리스트를 생성하는 것 보다 아래 처럼 한 줄로 생성하는 것이 훨씬 간결해보인다.
[i*j for i in range(1, 10) for j in range(1, 10) if i*j < 10]
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 2, 4, 6, 8, 3, 6, 9, 4, 8, 5, 6, 7, 8, 9]
두개의 for 문이 사용된 위 List Comprehension []안에 하나의 중첩된 리스트 표기법만을 사용할 수 있는 것은 아니다.
차이[이산]
한 객체 내에서 열와 열, 행과 행의 차이를 출력하는 메서드
df.diff(periods = 비교할 간격지정, 기본은 1(바로 이전 값과 비교), axis = (0인경우 행끼리, 1인경우 열끼리 비교))
import numpy as np
import pandas as pd
df = pd.DataFrame(np.arange(20).reshape(4, 5))
print(df)
# 0 1 2 3 4
# 0 0 1 2 3 4
# 1 5 6 7 8 9
# 2 10 11 12 13 14
# 3 15 16 17 18 19
예시로 사용할 데이터 프레임을 생성하였다.
axis=0 일 경우 행 - 바로 직전행의 값을 출력한다. 비교 값이 없으면 NaN출력
print(df.diff(axis=0))
# 0 1 2 3 4
# 0 NaN NaN NaN NaN NaN
# 1 5.0 5.0 5.0 5.0 5.0
# 2 5.0 5.0 5.0 5.0 5.0
# 3 5.0 5.0 5.0 5.0 5.0
axis=1 일 경우 열 - 바로 직전 열 의 값을 계산하여 출력. 역시나 비교 값이 없으면 NaN 출력
periods 라는 것을 사용할 수 있는데 + 값인 경우 이전 값과의 차를 - 의 경우는 뒷칸과의 값을 비교하게 된다
# 2칸 이전 값과 비교하는 경우
print(df.diff(periods = 2))
# 0 1 2 3 4
# 0 NaN NaN NaN NaN NaN
# 1 NaN NaN NaN NaN NaN
# 2 10.0 10.0 10.0 10.0 10.0
# 3 10.0 10.0 10.0 10.0 10.0
# 2칸 이후의 값과 비교
print(df.diff(periods = -2))
# 0 1 2 3 4
# 0 -10.0 -10.0 -10.0 -10.0 -10.0
# 1 -10.0 -10.0 -10.0 -10.0 -10.0
# 2 NaN NaN NaN NaN NaN
# 3 NaN NaN NaN NaN NaN
순회 가능한 객체를 생성하는 가장 간단한 방법. 일반함수는 실행되면 단일 값을 반환한느 반면 제너레이터는 순차적인 값을 요청시마다 하나씩 반환한다. 생성하려면 함수에서 return 하는 대신 yield 예약어를 사용
def squares(n = 10) :
print('1 to {0}'.format(n ** 2))
for i in range(1, n+1) :
yield i ** 2
제너레이터는 그대로 ex. squares() 을 호출한다고 해도 즉각 원하는 값이 출력되지 않는다. for문을 돌리며 값을 요청하면 그제야 제너레이터 내의 코드가 실행된다
for x in squares() :
print(x, end=' ')
# 1 to 100
# 1 4 9 16 25 36 49 64 81 100
생성하는 더 간단한 방법은 제너레이터 표현식을 사용하는 것이다. 리스트 표현식과 비슷하게 괄호를 사용하여 제너레이터를 생성할 수 있다.
gen = (x**2 for x in range(10))
for i in gen :
print(i, end=' ')
# 0 1 4 9 16 25 36 49 64 81
pandas에서는 서로 다른 index를 가진 객체간의 산술 연산이 가능하다. 서로 겹치는 index가 없을 경우 해당 데이터는 NA 값 처리되며, DataFrame의 정렬은 로우와 컬럼 모두에 적용된다.
df1 = pd.DataFrame(np.arange(9).reshape(3, 3), index = ['a', 'b', 'c'])
df2 = pd.DataFrame(np.arange(9).reshape(3, 3), index = ['a', 'd', 'c'])
print(df1)
# 0 1 2
# a 0 1 2
# b 3 4 5
# c 6 7 8
print(df2)
# 0 1 2
# a 0 1 2
# d 3 4 5
# c 6 7 8
print(df1 + df2)
# 0 1 2
# a 0.0 2.0 4.0
# b NaN NaN NaN
# c 12.0 14.0 16.0
# d NaN NaN NaN
공통되는 행이나 열이 없는 DataFrame을 더한다면 결과는 모두 NaN 이 뜬다. 만약 존재하지 않는 값을 지정된 값으로 하고 싶을 때는 다음과 같이 fill_value= 를 이용 할 수 있다.
print(df1.add(df2, fill_value=0))
# 0 1 2
# a 0.0 2.0 4.0
# b 3.0 4.0 5.0
# c 12.0 14.0 16.0
# d 3.0 4.0 5.0
print(df1.add(df2, fill_value=1000))
# 0 1 2
# a 0.0 2.0 4.0
# b 1003.0 1004.0 1005.0
# c 12.0 14.0 16.0
# d 1003.0 1004.0 1005.0
지정된 값 + 원래 본인 값이 결과에 들어가 있는 것을 확인할 수 있다.
| 메서드 | 설명 |
|---|---|
| add, radd | 덧셈을 위한 메서드 |
| sub, rsub | 뺄셈을 위한 메서드 |
| div, rdiv | 나눗셈을 위한 메서드 |
| floordiv, rfloordiv | 나눗셈(/)을 위한 메서드 |
| mul, rmul | 곱셈을 위한 메서드 |
| pow, rpow | 승(**)을 위한 메서드 |
arr = np.arange(12).reshape(3, 4)
arr[0]
# array([0, 1, 2, 3])
arr - arr[0]
# array([[0, 0, 0, 0],
# [4, 4, 4, 4],
# [8, 8, 8, 8]])
계산이 각 로우에 대하여 한번씩 잘 수행되었다. 이렇듯 특정 조건이 만족되면 크기가 같지 않아도 계산이 된다. 이를 브로드캐스팅 이라고 한다.
pandas의 많은 함수에서 index의 값은 유일해야하지만, 그것이 의무적이지는 않다.
import pandas as pd
obj = pd.Series(range(5), index = ['a', 'a', 'b', 'b', 'c'])
obj
# a 0
# a 1
# b 2
# b 3
# c 4
# dtype: int64
중복된 인덱스를 가진 객체를 하나 만들었다. 여기서 is_unique 속성을 사용해 인덱스 값이 유일한지 알아볼 수 있다.
obj.index.is_unique
# False
당연한 말이지만 중복되는 인덱스 값이 있다면 인덱스를 이용해 데이터의 접근시 원하는 대로 움직이지 않을 수 있다.
obj['a']
# a 0
# a 1
# dtype: int64
# 중복되는 인덱스로 접근했더니, 스칼라 값이 아닌 하나의 Serires 객체를 반환하는 모습
pandas 객체는 일반적인 수학 메서드와 통계메서드를 가지고 있으며 메서드의 대부분은 하나의 Series나 DataFrame 행 또는 열에서 단일 값(합이나 평균 같은 값)을 구하는 축소(reductions) 혹은 요약 통계(summary statistics) 범주에 속한다.
# 예제로 사용할 임의의 데이터프레임 생성
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randint(-10, 10, 10).reshape(2,5))
print(df)
# 0 1 2 3 4
# 0 7 0 -8 -8 -2
# 1 2 -4 -7 -2 -6
df = df.replace(-2, np.NaN)
print(df)
# 0 1 2 3 4
# 0 7 0 -8 -8.0 NaN
# 1 2 -4 -7 NaN -6.0
pandas의 메서드는 누락된 데이터를 제외하고 계산된다.
df.sum()
# 0 9.0
# 1 -4.0
# 2 -15.0
# 3 -8.0
# 4 -6.0
# dtype: float64
# axis=1 혹은 columns 명을 넘기는 것도 가능하다
df.sum(axis = 1)
# 0 -9.0
# 1 -15.0
# dtype: float64
# 만약 누락된 값을 제외하고 싶지 않다면 skipna 옵션을 꺼주면 된다
# 기본은 True
df.mean(axis=1, skipna=False)
# 0 NaN
# 1 NaN
# dtype: float64
| 옵션 | 설명 |
|---|---|
| axis | 연산을 수행할 축. DataFrame에서 0은 로우고 1은 컬럼 |
| skipna | 누락된 값을 제외할 것인가? 기본값은 True |
| level | 계산하려는 축이 다중 index라면 레벨에 따라 묶어 계산한다. |
#### idxmin, idxmax
최솟값 혹은 최대값을 가지고 있는 위치 반환
```python
print(df.idxmin())
# A ㄱ (a, 1)
# B ㄴ (a, 1)
# C ㄷ (a, 1)
# dtype: object
print(df.idxmax())
# A ㄱ (d, 4)
# B ㄴ (d, 4)
# C ㄷ (d, 4)
# dtype: object
계속하여 덧붙여 계산
df.cumsum()
# A B C
# ㄱ ㄴ ㄷ
# a 1 0 1 2
# b 2 3 5 7
# c 3 9 12 15
# d 4 18 22 26
| 메서드 | 설명 |
|---|---|
| count | NA 값을 제외한 값의 수를 반환 |
| describe | Series나 DataFrame의 각 컬럼에 대한 요약 통계를 계산 |
| min, max | 최소값, 최대값 |
| argmin, argmax | 최소값과 최대값을 담고있는 index의 위치 반환 |
| idxmin, idxmax | 최소값과 최대값을 담고있는 index의 값을 반환 |
| quantile | 0부터 1까지의 분위수를 계산 |
| sum | 합 계산 |
| mean | 평균 계산 |
| median | 중간값(50% 분위) 반환 |
| mad | 평균값에서 평균절대편차를 계산 |
| prod | 모든 값의 곱 |
| var | 표본분산의 값을 계산 |
| std | 표본표준편차의 값을 계산 |
| skew | 표본비대칭도(3차 적률)의 값을 계산 |
| kurt | 표본첨도(4차 적률)의 값을 계산 |
| cumsum | 누적합을 계산 |
| cummin, cummax | 누적 최소값과 누적 최댓값 계산 |
| cumprod | 누적곱 계산 |
| diff | 1차 산술차 계산(시계열 데이터 처리시 유용) |
| pct_change | 퍼센트 변화율을 계산 |
argmin과 idxmin의 차이
print(df.idxmin())
# A ㄱ (a, 1)
# B ㄴ (a, 1)
# C ㄷ (a, 1)
# dtype: object
print(np.argmin(df))
# 0
위 메서드 예시
a = np.arange(1, 10).reshape(3,3)
np.median(a) # 5.0
np.prod(a) # 362880
np.var(a) # 6.666666666666667
np.std(a) # 2.581988897471611
np.cumsum(a) # array([ 1, 3, 6, 10, 15, 21, 28, 36, 45])
np.cumprod(a) # array([ 1, 2, 6, 24, 120, 720, 5040, 40320, 362880])
np.diff(a)
# array([[1, 1],
# [1, 1],
# [1, 1]])