안녕하세요 미니빅입니다.
이번 시간은 지난 시간에 이어서 pandas의 DateFrame에 대해서 얘기해볼께요
1차원 값을 주로 넣었던 Series에 이어서,
2차원에서 주로 활용하는 DataFrame은 Series 여러개가 붙어있는 형태를 띄고 있습니다.
(list, dict의 형태를 이어서 쓰고 있다는 말이 되기도 하죠)
-DataFrame 생성(1) ->딕셔너리형태
import pandas as pd
data = {"fruits": ["apple", "orange", "banana", "strawberry",
"kiwifruit"],
"year": [2001, 2002, 2001, 2008, 2006],
"time": [1, 4, 5, 6, 3]}
df = pd.DataFrame(data)
print(df)
# fruits year time
# 0 apple 2001 1
# 1 orange 2002 4
# 2 banana 2001 5
# 3 strawberry 2008 6
# 4 kiwifruit 2006 3
DataFrame 생성에서도, 딕셔너리를 넣는 것이 가능합니다(Series 처럼)
여기서 포인트는, key들이 위로 올라가있죠.
dataframe(이하 df)은 key들이 column이라는 값으로도 불립니다.(series랑 헷갈리면 안 되요)
그래서
print(f"df.keys():{df.keys()}")
print(f"df.columns:{df.columns}")
#df.keys():Index(['fruits', 'year', 'time'], dtype='object')
#df.column:Index(['fruits', 'year', 'time'], dtype='object')
print(list(df.index)) #[0, 1, 2, 3, 4]
series에서 index = keys 였다면, df에서는 columns = keys가 됩니다.
index를 출력하니, series처럼 입력하지 않은 형태라서 0부터 시작한 값이 출력되는 걸 볼 수 있어요.
-DataFrame 생성(2) -> series 형태
import pandas as pd
index = ["apple", "orange", "banana", "strawberry", "kiwifruit"]
data1 = [10, 5, 8, 12, 3]
data2 = [30, 25, 12, 10, 8]
series1 = pd.Series(data1, index=index)
series2 = pd.Series(data2, index=index)
df = pd.DataFrame([series1, series2])
print(df)
# apple orange banana strawberry kiwifruit
# 0 10 5 8 12 3
# 1 30 25 12 10 8
sries의 columns 값이 동일하면, 새로 넣을 필요가 없습니다.
-행추가(append)
import pandas as pd
data = {"fruits": ["apple", "orange", "banana", "strawberry", "kiwifruit"],
"year": [2001, 2002, 2001, 2008, 2006],
"time": [1, 4, 5, 6, 3]}
df = pd.DataFrame(data)
series = pd.Series(["mango", 2008, 7], index=["fruits", "year", "time"])
print("series")
print(series)
# series
# fruits mango
# year 2008
# time 7
# dtype: object
df = df.append(series, ignore_index=True)
#ignore_index 매개변수를 True로 설정해야지 index를 무시하고 새로 추가가 가능합니다.
print(df)
# fruits year time
# 0 apple 2001 1
# 1 orange 2002 4
# 2 banana 2001 5
# 3 strawberry 2008 6
# 4 kiwifruit 2006 3
# 5 mango 2008 7
위를 보면, 딕셔너리 형태를 이용해서, df를 생생하고,
행을 추가해야하는 경우, append() 함수를 통해서 행을 추가하고, 값을 넣어줍니다.
append 함수는, ignore_index=False 가 기본값인지라, 다음과 같은 경우에 편히 넣을 수 있습니다.
df_1 = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
'B': ['B0', 'B1', 'B2'],
'C': ['C0', 'C1', 'C2'],
'D': ['D0', 'D1', 'D2']},
index=[0, 1, 2])
# A B C D
# 0 A0 B0 C0 D0
# 1 A1 B1 C1 D1
# 2 A2 B2 C2 D2
df_2 = pd.DataFrame({'A': ['A3', 'A4', 'A5'],
'B': ['B3', 'B4', 'B5'],
'C': ['C3', 'C4', 'C5'],
'D': ['D3', 'D4', 'D5']},
index=[3, 4, 5])
# A B C D
# 3 A3 B3 C3 D3
# 4 A4 B4 C4 D4
# 5 A5 B5 C5 D5
print(df_1)
print(df_2)
item = df_1.append(df_2)
print(item)
# A B C D
# 0 A0 B0 C0 D0
# 1 A1 B1 C1 D1
# 2 A2 B2 C2 D2
# 3 A3 B3 C3 D3
# 4 A4 B4 C4 D4
# 5 A5 B5 C5 D5
dataframe을 추가해줄 경우에는 문제가 없으나,
시리즈 등으로 추가하는 경우는 위와 같이 매개변수(ignore_index)를 True로 해줘야 합니다.
-열추가
import pandas as pd
index = ["apple", "orange", "banana", "strawberry", "kiwifruit"]
data1 = [10, 5, 8, 12, 3]
data2 = [30, 25, 12, 10, 8]
series1 = pd.Series(data1, index=index)
series2 = pd.Series(data2, index=index)
new_column = pd.Series([15, 7], index=[0, 1])
df = pd.DataFrame([series1, series2])
df["mango"] = new_column
# apple orange banana strawberry kiwifruit mango
# 0 10 5 8 12 3 15
# 1 30 25 12 10 8 7
df["새로운 컬럼"] = 값,의 형태로 만들어서 입력하면 추가됩니다.
-데이터 참조 (1) ->key 검색
df는 딕셔너리와 리스트 형태에서 따와서 둘 다 검색이 가능합니다.
하지만, series에서 keys값들이 column이 되서, 실질적으로 검색시, columns들을 기준으로 검색됩니다.
data = {"fruits": ["apple", "orange", "banana", "strawberry", "kiwifruit"],
"year": [2001, 2002, 2001, 2008, 2006],
"time": [1, 4, 5, 6, 3]}
df = pd.DataFrame(data)
# fruits year time
# 0 apple 2001 1
# 1 orange 2002 4
# 2 banana 2001 5
# 3 strawberry 2008 6
# 4 kiwifruit 2006 3
print(df["year"])
# 0 2001
# 1 2002
# 2 2001
# 3 2008
# 4 2006
# Name: year, dtype: int64
print(df["year"][1])
# 2002
keys값(columns 이름)들로 column을 추출하고, 그 값에서 row갑을 재검색하는 예를 보여주고 있습니다.
list나 array와 같이 검색을 하고 싶다면, 또는 index_num로 검색을 하고 싶다면
loc/iloc 함수를 써야합니다.
-데이터 참조 (2) ->loc 검색
import pandas as pd
data = {"fruits": ["apple", "orange", "banana", "strawberry", "kiwifruit"],
"year": [2001, 2002, 2001, 2008, 2006],
"time": [1, 4, 5, 6, 3]}
df = pd.DataFrame(data,index ="a b c d e".split())
df = df.loc[["b","c"],["time","year"]]
#1번째 경우
print(df)
# time year
#b 4 2002
#c 5 2001
#2번째 경우
df = df.loc["b":"c"]["time"]
print(df)
#b 4
#c 5
#Name: time, dtype: int64
loc - 의 경우엔 index, columns의 순서대로 값을 넣어주어야합니다. (행, 열) 그리고, 넣어지는 값은 index 이름이나 column의 이름으로 검색해야 합니다.
경우를 상세히 살펴보면 1번째 경우 같으면, loc 함수의 범위에 각각의 index이름과 column의 이름을 통해서 탐색을 한 경우이고,
2번째 경우는 index이름(b,c)로 탐색을 하고나서, column의 이름(key)의 형태로 검색을 한 것으로 보입니다.
여기서 중요한 점 하나는, 우리가 일반적으로 했던 index(번호) 탐색은 1:5 와 같이 표시하면,
1~4까지 선택하여 (마지막 번호 - 1) 였으나, loc과 같이 이름으로 하게 될 경우, 끝도 포함하게 됩니다.
이어서 iloc 함수를 살펴볼께요
-데이터 참조 (2) ->iloc 검색
import pandas as pd
data = {"fruits": ["apple", "orange", "banana", "strawberry", "kiwifruit"],
"year": [2001, 2002, 2001, 2008, 2006],
"time": [1, 4, 5, 6, 3]}
df = pd.DataFrame(data)
print(df)
# fruits year time
# 0 apple 2001 1
# 1 orange 2002 4
# 2 banana 2001 5
# 3 strawberry 2008 6
# 4 kiwifruit 2006 3
#1번째
df = df.iloc[[1, 3], [0, 2]]
print(df)
# fruits time
# 1 orange 4
# 3 strawberry 6
print(type(df))
#<class 'pandas.core.frame.DataFrame'>
#2번째 경우
df = df.iloc[[1,3]]["year"]
print(df)
# 1 2002
# 3 2008
print(type(df))
# Name: year, dtype: int64
# <class 'pandas.core.series.Series'>
#error
df = df.iloc[[1, 3]][0]
print(df)
iloc 함수는 기본적으로 [ ](대괄호) 안에 행,열 번호 순서를 쓰면 됩니다. 가령 [1:2, 2:4]라던지, [[1,3],[3,4]]라던지요.
1번째 경우는 심플합니다. iloc의 행번호, 열번호 그대로 넣었습니다.
type도 dataframe이 유지되고 있습니다.
하지만 2번째 경우는 iloc 함수 이후, "year"이라는 key 값으로 검색합니다.
type도 series로 잡히죠. 여기서도 딕셔너리나, series처럼 key 검색으로 열을 선택해준 겁니다.
에러케이스를 보면,
열에 대해서는 기본적으로 번호 탐색이 불가능합니다.
번호로 하고 싶다면, iloc으로 탐색하고,
아니라면, loc 함수 / key 검색을 해야하는 거죠.
위의 케이스를 섞으면 이와 같은 경우도 가능할겁니다.
df = df["year"]
print(type(df))
# <class 'pandas.core.series.Series'>
print(df)
# 0 2001
# 1 2002
# 2 2001
# 3 2008
# 4 2006
print(df[2])
# 2001
key검색을 한 후에, 자료형은 series로 바뀝니다.
여러개의 key, item가 있던 df -> series가 되는 거죠.
이때부턴 iloc,loc가 불가능합니다. df에 속해있는 함수이기에, series에서 했던 것처럼 index 번호로 찾으면 됩니다.
항상 자료형이, 파이썬에서, 코딩에서 기본이자 근간이 된다고 생각하기에 자료형을 꼭 생각해주시길 바랍니다.
-행/열 삭제(drop)
import pandas as pd
data = {"fruits": ["apple", "orange", "banana", "strawberry", "kiwifruit"],
"year": [2001, 2002, 2001, 2008, 2006],
"time": [1, 4, 5, 6, 3]}
df = pd.DataFrame(data)
# #1번째
# df = df.drop(1)
# print(df)
# # fruits year time
# # 0 apple 2001 1
# # 2 banana 2001 5
# # 3 strawberry 2008 6
# # 4 kiwifruit 2006 3
#2번째
df = df.drop("year",axis=1)
print(df)
# fruits time
# 0 apple 1
# 1 orange 4
# 2 banana 5
# 3 strawberry 6
# 4 kiwifruit 3
행/열 삭제 둘 다 가능합니다.
여기서 포인트는 axis 라는 매개변수!
기본값이 0으로 설정되서, 그냥 값을 넣으면 행(0)이 삭제됩니다.
pandas에서는 "0" - "1차원", "1" - "2차원" 해서 순차적으로 올라갑니다.
-행/열 정렬
series에서 확장된 df은 행/열 중심 정렬이 가능합니다.
import pandas as pd
data = {"fruits": ["apple", "orange", "banana", "strawberry", "kiwifruit"],
"year": [2001, 2002, 2001, 2008, 2006],
"time": [1, 4, 5, 6, 3]}
df = pd.DataFrame(data)
print(df)
# fruits year time
# 0 apple 2001 1
# 1 orange 2002 4
# 2 banana 2001 5
# 3 strawberry 2008 6
# 4 kiwifruit 2006 3
df = df.sort_values("fruits")
print(df)
# fruits year time
# 0 apple 2001 1
# 2 banana 2001 5
# 4 kiwifruit 2006 3
# 1 orange 2002 4
# 3 strawberry 2008 6
df = df.sort_index(axis=1)
print(df)
# fruits time year
# 0 apple 1 2001
# 2 banana 5 2001
# 4 kiwifruit 3 2006
# 1 orange 4 2002
# 3 strawberry 6 2008
df = df.sort_index()
print(df)
# fruits time year
# 0 apple 1 2001
# 1 orange 4 2002
# 2 banana 5 2001
# 3 strawberry 6 2008
# 4 kiwifruit 3 2006
df는 series에서 이어서, sort_values와 sort_index 함수 둘 다 사용가능합니다.
1)sort_values는 원하는 column의 이름 순으로 정렬이 되며, 여러개의 column을 넣어도 됩니다.
2)sort_index는 index 번호 순으로 정렬합니다 (역시 열 정렬, column정렬이죠)
하지만, sort_index에 axis 라는 매개변수가 있어서, axis=1을 하면, key 값 기준으로 정렬이 가능합니다.
물론, sort_values에도 axis는 존재합니다만, value(ex> "apple","2001")은 숫자, 문자가 섞여 있어서 쓰기 쉽지 않습니다.
-필터링-
seriese에 이어서 df에서도 이어서 필터링을 통해 원하는 값만 받아올 수 있습니다.
import pandas as pd
data = {"fruits": ["apple", "orange", "banana", "strawberry", "kiwifruit"],
"year": [2001, 2002, 2001, 2008, 2006],
"time": [1, 4, 5, 6, 3]}
df = pd.DataFrame(data)
print(df)
# fruits year time
# 0 apple 2001 1
# 1 orange 2002 4
# 2 banana 2001 5
# 3 strawberry 2008 6
# 4 kiwifruit 2006 3
print(df.index % 2 == 0)
print()
print(df[df.index % 2 == 0])
# [ True False True False True]
# fruits year time
# 0 apple 2001 1
# 2 banana 2001 5
# 4 kiwifruit 2006 3
역시 series와 유사합니다. 그러기에 설명은 줄이겠습니다.
여기까지 해서, dataframe에 대한 기본 구조 및 기초적 함수에 대한 설명이였으며,
그 다음에는 pandas의 좀 활용도가 높은 함수에 대해서 정리할께요.
해당 내용은 한빛미디어의 파이썬으로 배우는 밑바닥 교과서 내용을 기본으로 첨언 했습니다
안녕!