LITTLE BY LITTLE

파이썬 기초 - 조건문, Numpy, Pandas 본문

데이터 분석/파이썬 Basic & EDA

파이썬 기초 - 조건문, Numpy, Pandas

위나 2022. 7. 15. 12:08

If문

money = False
if money:
    print("택시를 타고 가라")
else:
     print("걸어가라")
     
if money:
    print("택시를")
    print("타고")
    print("가라")
    
  money = 2000
card = True
if money>=3000 or card:
    print("택시를 타고 가라")
else:
    print("걸어 가라")
    
 'a' in ('a','b','c')   
 
 'j' not in 'python'
 
 pocket = ['paper','cellphone','money']
if 'money' in pocket:
    print("택시를 타고 가라")
else:
    print("걸어 가라")
    
    
pocket = ['paper','cellphone']
card = True
if 'money' in pocket:
    print("택시를 타고 가라")
elif card: #elif는 이전 조건문이 거짓일 때 (=or if)
    print("택시를 타고 가라")
else:

score=60
if score >=60:
    message = "success"
else:
    message = "failure"

#위 코드를 조건부 표현식으로 간단히
message="success" if score>=60 else "failure"
    print("걸어 가라")

While 문

  1. 0에서 시작, treeHit가 10번 미만일 때, 1씩 더해가며 몇번 찍었는지 출력
  2. print("나무를 %d번 찍었습니다,%treeHit)
treeHit=0
while treeHit < 10:
    treeHit = treeHit + 1
    print("나무를 %d번 찍었습니다." %treeHit)
if treeHit == 10:
    print("나무 넘어갑니다")
  1. number변수에 0먼저 대입
  2. while number!=4 를 이용하여, 4가 아닐 시 계속 prompt 출력, 4입력시 while문 빠져나가게 만듦
prompt = """
1. Add
2. Del
3. List
4. Quit
Enter number : """

number = 0
while number !=4:
    print(prompt)
    number= int(input())

위 코드는 무한루프 돌게되는 잘못된 코드

coffee = 10
money=300
while True:
    money = int(input("돈을 넣어주세요:"))
if money == 300:
    print("커피를 줍니다.")
    coffee = coffee - 1
elif money > 300:
    print("거스름돈은 %d를 주고 커피를 줍니다.") %(money-300)
    coffee = coffee -1
else:
    print("돈을 다시 돌려주고 커피를 주지 않습니다.")
    print("남은 커피의 양은 %d개 입니다." % coffee)
if coffee == 0:
    print("커피가 다 떨어졌습니다. 판매를 중지합니다.")
break

▲ 수정된 코드

▼ 만약 while문을 빠져나가지 않고 맨 처음으로 돌아가게 만들고 싶은 경우

a = 0
while a <10 : #a<10 이 맨처음으로 돌아가게 만드는 명령어이다.
    a = a+1
    if a % 2 == 0: continue #2로 나누었을 때 나머지가 0 인경우 = 짝수인 경우 a+1하지않고 다음 수로 continue한다는 소리
    print(a)

무한루프

while True:
    print("Ctrl+C를 눌러야 while문을 빠져나갈 수 있습니다")

For문

test_list=['one','two','three']
for i in test_list:
    print(i)
    
 a = [(1,2),(3,4),(5,6)]
 for (first,last) in a:
     print(first+last)

총 5명의 학생. 점수가 60점 넘을시 합격, 아닐시 불합격

marks = [90,25,67,45,80]
number=0
for mark in marks:
    number=number+1
    if mark>=60:
        print("%d번 학생은 합격입니다." % number)
    else:
        print("%d번 학생은 불합격입니다." % number)

while문에 쓰이는 continue 문 사용

marks = [90,25,67,45,80]
number=0
for mark in marks:
    number=number+1
    if mark<60: continue # 아래 print를 하지않고 그냥 지나가라는 의미(합격이아님)
    print("%d번 학생 축하합니다. 합격입니다."%number)

for문은 숫자 리스트를 자동으로 만들어주는  range함수와 함께 자주 사용됨

* range() : 끝 숫자 포함 안함 주의

add=0
for i in range(1,11):
    add = add + i
print(add)

marks=[90,25,67,45,80]
for number in range(len(marks)):
    if marks[number]<60: continue
    print("%d번 학생 축하합니다. 합격입니다."%(number+1))

 → range(len(marks))라서 0부터 글자수-1 인 4까지라서, 1번부터 5번까지로 계산해야되기때문에 +1 해준 것

#구구단
for i in range(2,10):
    for j in range(1,10):
        print(i*j,end="")
        print('')

리스트 안에 for문을 포함하는 리스트 내포 사용하기

# 리스트 내포 적용 전
a=[1,2,3,4]
result=[]
for num in a:
    result.append(num*3)
    print(result)
# 리스트 내포 적용 후
a=[1,2,3,4]
result=[num*3 for num in a]
print(result)

리스트 내포 안에 if조건 사용하기 (짝수에만 3곱하기)

a=[1,2,3,4]
result=[num*3 for num in a if num%2 ==0]
print(result)
import pandas as pd
import numpy as np

# 구구단의 모든 결과 리스트에 담기
result=[x*y for x in range(2,10)
             for y in range(1,10)]
print(result)

함수

add 함수 , def add(a,b) & return a+b

def add(a,b):
    return a+b
a=3
b=4
c=add(a,b)
print(c)

result = a+b를 def add(a,b)와 return a+b사이에 추가

def add(a,b):
    result = a+b
    return(result)
a=add(3,4)
print(a)
def add(a,b):
    print("%d,%d의 합은 %d입니다."%(a,b,a+b))
add(3,4)
a = add(3,4)
print(a)
#결과값은 오직 return 명령어로만 돌려받을 수 있다.

입력값, 결과값도 없는 함수

def say():
    print('Hi')
    say()

매개변수 지정하여 호출하기 (출력값에 들어갈 변수를 미리 정해놓음)

def add(a,b):
    return a+b
    result=add(a=3,b=7)
print(result)

입력값이 몇개인지 모를 때, *args 사용 => 복수개의 인자를 함수로 받고자할 때 쓰임, *를 붙이고 args가 아닌 다른 이름으로 지정해도 무방

def add_many(*numbers):
    result=0
    for i in args:
        result=result+i
    return result
    result=add_many(1,2,3)
print(result)

적용하고자 하는 함수도 여러개일 때, def 함수명(choice*args):  입력

def add_mul(choice,*args):
    if choice == "add":
        result == 0
        for i in args:
            result=result+i
        return result
    result = add_mul('add',1,2,3,4,5)
print(result)
def add_and_mul(a,b):
    return a+b,a*b
    result = add_and_mul(3,4)
    result = (7,12)
    result1, result2 = add_and_mul(3,4)
def add_and_mul(a,b):
    return a+b
    return a*b
    result = add_and_mul(2,3)
    print(result)

def문은 return문을 만나는 순간 결과값을 돌려준 다음 바로 다음함수로 빠져나감

def say_myself(name,old,man=True):
    print("나의 이름은 %s입니다." %name)
    if man:
        print("남자입니다.")
    else:
        print("여자입니다.")
        say_myself("박응용",27) 
say_myself("박응용",27,True)

함수 안에서 선언한것과 밖은 당연히 서로 영향을 주지 않음

a=1
def vartest(a):
    a=a+1
vartest(a)
print(a) #1

영향을 주게 만드려면 return 함수 사용 (global 명령어를 사용하는 방법도 있지만 return이 더 나음)

# return 함수 사용
a=1
def vartest(a):
    a=a+1
    return a
a=vartest(a)
print(a)

 

람다 함수 (lambda 변수 : 적용하고자 하는 식) 

 

  1. def를 사용해야할 정도로 복잡하지 않거나, def를 사용할 수 없는 곳에 쓰인다.
  2. return 명령어가 없어도 결과값을 돌려줌
  3. =익명함수
  4. 함수 만들 때 코드를 간단히 할 수 있다는 장점
  5. 예를 들어 target = [ ' cat ' , ' tiger ' , ' dog ' , ' snake ' ]  다음과 같은 문자 정렬시 앞 뒤 공백을 제외한 문자의 길이로 정렬하고자 한다면, my_key라는 함수를 생성한 다음에, 이번 정렬에만 쓰이고 재사용할 일이 없는 함수이기에 lambda함수로 생성해서 넘겨주는것이 좋다. lambda x : (정의했던 함수의 return 부분)

 

# 람다 함수 이용
add = lambda a,b:a+b
result=add(3,4)
print(result)

# 일반 함수 def 이용
def add(a,b):
    return a+b
result = add(3,4)
print(result)
def my_key(string):
    return len(string.strip())
target=[' cat','tiger',' dog','snake ']
print(sorted(target,key=my_key))


target=['cat','tiger','dog','snake']
print(sorted(target,key=lambda x : len(x.strip())))

 

apply 사용 & lambda 함수

def agetrans(x):
    if x<25:
        return 1
    elif x<30:
        return 2
    else:
        return 3
train_data["Agegroup2"]=train_data.Age.apply(lambda x:agetrans(x))

 


사용자 입출력

# input
number = input("숫자를 입력하세요")
print(number)

#print
print("life","is","too","short") # 콤마 입력시, 문자열 띄어쓰기 역할
print("life"+"is"+"too"+"short")

파일 읽고 쓰기

f = open("새파일.txt",'r') #읽기모드
f = open("새파일.txt",'w') #쓰기모드
f = open("새파일.txt", 'a') #추가모드
f.close()

파일을 쓰기모드로 열어서 출력값 적기

# 화면이 아닌 파일에 결괏값을 적는 방법
f = open("경로/새파일.txt",'w')
for i in range(1,11):
    data="%d번째 줄입니다.ln" %i
    f.write(data)
f.close()
# 화면에 결괏값 출력됨
for i in range(1,11):
    data="%d번째 줄입니다.ln" %i
    print(data)

.readlines() 함수

f=open(경로/새파일.txt,'r')
line = f.readline()
print(line)
f.close()
f = open(경로/새파일.txt,'r')
lines=f.readlines()
for line in lines: # for문과 같이 사용
    print(line)
f.close()

.readline() 으로 모든 줄 읽어서 출력하기

f = open(경로/새파일,'r')
while True:
    line = f.readline() # while문으로 한 줄씩 읽는 명령어 계속 반복
    if not line: break  # 더이상 읽을 줄이 없을 때 break를 수행한다.
    print(line)
f.close()

사용자의 입력을 받아서 출력하는 예시

while 1:
    data = input()
    if not data: break
    print(data)

open() → read() 파일 내용 전체를 문자열로 돌려준다.

f = open(경로/새파일.txt,'r')
data = f.read()
print(data)
f.close()

파일에 새로운 내용 추가

f = open(경로/새파일.txt,'a')
for i in range(11,20):
    data="%d번째 줄입니다.ln" %i
    f.write(data)
f.close()

with 문과 함께 사용하기 (자동으로 f.closes() 수행됨)

with open("foo.txt","w") as f:
f.write("Life is too short, you need python")

Numpy (연산에 사용)

np.array([ ])

a = np.array([0,1,2,3])
print(a) # 일반 '리스트'와 동일한 결과 - but,연산시 리스트보다 나아서 사용하는 것
print(type(a))
# ndim, shape
print(a.ndim)
print(a.shape)

#인덱싱, 슬라이싱
a= np.array([[0,1,2],[3,4,5]]) #리스트 두개이상 묶을 때 대괄호 한번 더 써주기
print(a)
#indexing
print(a[0,0])
print(a[0,1])
print(a[-1,-1]) #앞에서부터는 첫번째가 0이지만, 뒤에서부터는 첫번째가 -1임 주의

#slicing
b=np.array([[0,1,2,3],[4,5,6,7]])
print(b)
print(b[0,:]) #0번째 row에서 전체 다
print(b[:,1]) #전체 row에서 2번째 원소들만
print(b[:,0:3]) #전체 row에서 1번째부터 3번째 원소 
#(주의) 숫자로 슬라이싱 할 때에는 마지막 문자"전"까지 출력함
# (그래서4번째 전인 3번째원소까지 출력)

 

ndarray의 fancy indexing(행렬 인덱싱)

  • 불리안 방식 - true 인 원소만 선택, 인덱스 크기와 행렬 크기가 같아야함
  • 정수 인덱스 방식 - 지정된 위치의 원소만 선택 , 인덱스 크기와 행렬 크기가 달라도 됨
# 1. 불리안 방식
a = np.array([0,1,2,3,4,5])
idx=np.array([True,False,True,False,True,False])
print(a[idx]) #[0 2 4]
 
# 2. 정수 인덱스 방식
a = np.array([0,1,2,3,4]) *10
idx=np.array([0,2,4])
print(a[idx]) # [0 20 40] #[0 20 40]
# 정수 인덱스 방식은 중복되는 인덱스를 넣어 출력하는 것도 가능
a = np.array([0,1,2,3,4]) *10
idx=np.array([0,0,0,0,0,0,1,1,1,2,2,2,])
print(a[idx # [0 0 0 0 0 0 10 10 10 20 20 20]

Pandas

  • series와 data frame 둘다 index-value 조합, 차이는 series 1차원, data frame은 2차원 
  • [대괄호]는 1.리스트 정의 / 2.인덱싱
  • {중괄호}는 1.딕셔너리 정의
  • (소괄호)는 1. 튜플 정의 / 2. 연관순서 정의 *즉, 연산에는 소괄호만 쓰임

난수 생성하기

 

Np.random.random / Np.random.seed / Np.random.randint ( start, stop, mxn[행렬의 크기]) : 균일 분포 난수 생성

np.random.seed(123)
df=pd.DataFrame(np.random.randint(0,10,(4,4)),index=[2,4,1,3],columns=list("ABCD"))
df

df.sort_values(["A","B"],ascending=[True,False])

df.sort_index() #인덱스인 3,1,2,4를 오름차순으로 정렬

Pandas - 시리즈 Series

s=pd.Series([1,1,2,3,2,1,2,3,np.NaN,1,1,3])
print(s)

print(s.size) #size : 원소 개수 반환
print(s.shape) #shape : 튜플형태로 shape(mxn형태) 반환
print(s.unique()) #unique : 유일한 값만 ndarray로 반환 #함수 뒤에 () 소괄호 써주기
print(s.count()) #count : 결측치 제외 개수 반환

print(s.mean()) #mean : 결측치 제외 평균 반환
print(s.value_counts()) #count : 결측치 제외 개수 반환 (Pandas에서 결측치는 자동제외)
print(s.value_counts(dropna=False)) # 결측치 포함 개수 반환
print(s[[5,6,7,8,9,11]].value_counts()) # 변수에서 해당 리스트의 결측치 제외 개수 반환

Series 연산

s1=pd.Series([1,2,3,4],index=["a","b","c","d"])
s2=pd.Series([1,2,3,4],index=["d","c","b","a"])
print(s1+s2)
print(s1["a":"c"]) #문자로 슬라이싱할 시 마지막 문자까지 포함

np.arange VS range 함수

 

* 넘파이 arange와 기본 range 함수와 비교 : 넘파이는 실수단위까지 표현 가능 +  결과의 연산이 가능

 

→ 결론 : for문 등에서 정수를 다룰시에만 np.arange보다 range가 더 유리함

a=np.arange(10)
print(a)
b=np.arange(1,10,2) # (시작점,끝점[미포함],step size)
print(b)
c=np.arange(9,-2,-1.5)
print(c)

np.arange(1,5,0.5)
#range(1.5,0.5) -> 에러

np.arange(1,5)*2
#range(1,5)*2 -> 에러

for i in reversed(range(10)): #range(횟수) / range(시작,끝,증가폭)
    print('Hello,world!',i)

논리 인덱싱

# 논리 인덱싱
s=pd.Series(np.arange(10),index=np.arange(10)+1) 
print(s)
s[1:3]
print(s>7)
print(s[s>7]) #결과 차이 확인
print(s[s>=7].count()) #인덱싱으로 불러온 시리즈 뒤에 함수 붙일 수 있음

Pandas - 데이터프레임 DataFrame

  • .index 행 속성 확인
  • .column 열 속성 확인
  • .shape(mxn) 크기를 튜플()로 표현
  • .describe() 기초통계량 출력
  • .info() 데이터 타입, 각 아이템의 개수 출력

# series로 dataframe 생성
a=pd.Series([100,200,300],index=["a","b","c"])
b=pd.Series([101,201,301],index=["a","b","f"])
c=pd.Series([102,202,302],index=["a","b","c"])
pd.DataFrame([a,b,c],index=[100,101,102])

# dictionary로 dataframe 생성
d={"a":100,"b":200,"c":300}
print(pd.DataFrame(d,index=[1]))
d1={"a":200,"b":2,"c":3}
print(pd.DataFrame([d,d1],index=[1,2]))

csv파일 읽어오기 - index_col : 인덱스로 사용할 컬럼 설정 / Usecols : 실제로 dataframe에 로딩할 columns설정

#csv파일 읽어오기
pd.read_csv(filepath,sep=".",header=True,index_col=None,usecols=None)
# or
dpath=".///"
df=pd.read_csv(dpath+"파일명",usecols=["a","b","c"])

특정 column  인덱스로

df.index=df.지정하고싶은 컬럼명

row 선택하기

  1. .loc 인덱스 이름으로 선택 (행,열 동시 선택)
  2. .iloc 정수형 숫자 위치 인덱스 번호로 선택
train_data.loc[[201,202,203],["Name","Sex","Age"]] #->행과 열을 동시에 선택함.
train.data.iloc[[1,2,3]] #->위 아래 코드는 같은 결과 출력

* 인덱싱은 기본적으로 "열" 선택이다. a:b 슬라이싱 이용시, 행 선택 가능

 

train_data[1] -> 에러
train_data[1:4] (o)

데이터 속 변수 선택시, [대괄호] 말고도 .(온점)으로도 가능, 아래 코드에서 train.data.Age (o)

# 논리 인덱싱 - 1등석에 탔으면서 30대인 사람들
Pclass_=train_data["Pclass"]==1
Age_=(train_data.Age>=30)&(train_data.Age<40) 
# 두개 합치면 됨. print(Pclass_&Age_)
# 결과값은 논리형(bool)

* 원래 [대괄호]는 열로 출력하는데, 슬라이싱과 논리벡터는 행으로 자동 변환된다.

 

데이터프레임 변경

train_data["새로운변수명"]=train_data.Age*2

* (소괄호) 안에서 연산시에는 따옴표 불필요

train_data["Age_tripple"]=(train_data.Age+train_data.Age_double)

.insert ( 원하는 열 번호, 새로운 변수명, 변수 생성 방법) : 원하는 위치에 추가 가능 , [대괄호]로 추가할시 무조건 오른쪽에 추가되는데, 추가하고자 하는 열 위치 지정하고싶을 때 사용함

train_data.insert(3,"Fare10",train_data.Fare/10)

dictionary 로 변수 생성

dict_={"male":1,"female":0}
train_data["male"]=[dict_[i]for i in list(train_data.Sex)]

변수 drop

train_data.drop("male",axis=1,inplace=True)

 

Comments