0926 - Python

오늘·2022년 9월 27일
0

A

목록 보기
21/46

복습문제

# [[[ 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'}

enumerate

열거하다라는 뜻으로 순서가 있는 자료형(리스트, 튜플, 문자열)을 받아 인덱스 값을 포함하는 객체를 돌려준다.
(0908 - Python)

test = ["a", "b", "c"]
for i, j in enumerate(a) :
  print(i, j)
>
0 a
1 b
2 c

# i가 인덱스 j가 값

리스트 표기법(List Comprehension)

간결한 표현으로 새로운 리스트를 만들 수 있다

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 []안에 하나의 중첩된 리스트 표기법만을 사용할 수 있는 것은 아니다.

diff()

차이[이산]
한 객체 내에서 열와 열, 행과 행의 차이를 출력하는 메서드
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]])

계산이 각 로우에 대하여 한번씩 잘 수행되었다. 이렇듯 특정 조건이 만족되면 크기가 같지 않아도 계산이 된다. 이를 브로드캐스팅 이라고 한다.

중복 index

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라면 레벨에 따라 묶어 계산한다.
**index level** : 바깥쪽 인덱스부터 차례대로 상위 계층(level) 인덱싱 ```python df = pd.DataFrame(np.arange(12).reshape(4, 3), index=[['a', 'b', 'c', 'd'], [1, 2, 3, 4]], columns = [['A', 'B', 'C'], ['ㄱ', 'ㄴ', 'ㄷ']]) print(df) # A B C # ㄱ ㄴ ㄷ # a 1 0 1 2 # b 2 3 4 5 # c 3 6 7 8 # d 4 9 10 11

인덱스의 ‘a’부터 ‘d’까지가 맨 첫 번째 층, 정수로된 인덱스가 두 번째 층

층 = level

#### 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

누산(accumulation)

계속하여 덧붙여 계산

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]])

0개의 댓글