python data analysis library
데이터 조작, 정제, 분석, 시각화 등을 위한 기능을 제공
자료형: Series, DataFrame
$ pip install pandas
import numpy as np
import pandas as pd
파이썬에서 해당 패키지를 사용하기 위해 불러오는 과정을 실행한다
my_df = {'이름': ['Alice', 'Bob', 'Charlie', 'David'],
'나이': [25, 30, 35, 40],
'성별': ['여성', '남성', '남성', '남성']}
df = pd.DataFrame(my_df)
print(df)
이름 나이 성별
0 Alice 25 여성
1 Bob 30 남성
2 Charlie 35 남성
3 David 40 남성
my_2d_array = np.array([[25, 30, 35, 40], [35, 45, 55, 30]])
print(pd.DataFrame(my_2d_array))
0 1 2 3
0 25 30 35 40
1 35 45 55 30
dict = {'a' : [1,2,3], 'b' : [4,5,6], 'c' : [7,8,9]}
print(pd.DataFrame(dict))
a b c
0 1 4 7
1 2 5 8
2 3 6 9
series = pd.Series({'United Kingdom':'London',
'India':'New Delhi',
'United States':'Washington',
'Belgium':'Brussels'})
print(pd.DataFrame(series))
0
United Kingdom London
India New Delhi
United States Washington
Belgium Brussels
df = pd.read_csv('WORK_R/mushrooms.csv', sep = ',')
print(df.head(3))
class cap-shape cap-surface ... spore-print-color population habitat
0 p x s ... k s u
1 e x s ... n n g
2 e b s ... n n m
my_df = pd.DataFrame(data=np.array([[1,2,3], [4,5,6]]), index = range(1,3), columns = ['A','B','C'])
my_df.info()
[3 rows x 23 columns]
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2 entries, 1 to 2
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 A 2 non-null int32
1 B 2 non-null int32
2 C 2 non-null int32
dtypes: int32(3)
memory usage: 156.0 bytes
pd.options.display.max_rows = 20 # 최대 표시 행수
pd.set_option('display.min_rows', 5) # 최소 표시 행수
df = pd.read_csv('WORK_R\mushrooms.csv', sep = ',').iloc[:,0:7]
print(df)
class cap-shape cap-surface cap-color bruises odor gill-attachment
0 p x s n t p f
1 e x s y t a f
... ... ... ... ... ... ...
8122 p k y n f y f
8123 e x s n f n a
[8124 rows x 7 columns]
df = pd.DataFrame({'A':[11,21,31], 'B':[12,22,32], 'C':[13,23,33]}
, index=['1st','2nd','3rd'])
print(df.shape) # 행과 열의 수
print(len(df.index)) # 인덱스(행)의 갯수
(3, 3)
3
df = pd.DataFrame({'A':[11,21,31], 'B':[12,22,32], 'C':[13,23,33]}
, index=['1st','2nd','3rd'])
print(df)
display(df) # HTML로 출력
A B C
1st 11 12 13
2nd 21 22 23
3rd 31 32 33
A B C
1st 11 12 13
2nd 21 22 23
3rd 31 32 33
df = pd.DataFrame({'A':[11,21,31], 'B':[12,22,32], 'C':[13,23,33]}
, index=['1st','2nd','3rd'])
df.loc['4th'] = [41, 42, 43]
df.loc['8th'] = [81, 82, 83]
print(df)
A B C
1st 11 12 13
2nd 21 22 23
3rd 31 32 33
4th 41 42 43
8th 81 82 83
df['D'] = [14, 24, 34, 44, 84]
print(df)
A B C D
1st 11 12 13 14
2nd 21 22 23 24
3rd 31 32 33 34
4th 41 42 43 44
8th 81 82 83 84
df.drop('D', axis = 1, inplace = True)
print(df)
inplace는 삭제 후 다시 저장하는 것 의미. 디폴트 값은 False
A B C
1st 11 12 13
2nd 21 22 23
3rd 31 32 33
4th 41 42 43
8th 81 82 83
-만약 False로 바꾸면
df.drop('D', axis = 1, inplace = False)
print(df)
KeyError: "['D'] not found in axis"
에러가 뜨는 것을 볼 수 있다.
df.drop(['4th','8th'], axis = 0, inplace = True)
print(df)
A B C
1st 11 12 13
2nd 21 22 23
3rd 31 32 33
df = pd.DataFrame({'A':[11,21,31], 'B':[12,22,32], 'C':[13,23,33]}
, index=['1st','2nd','3rd'])
print(df['B'])
print(df[['A', 'C']])
1st 12
2nd 22
3rd 32
Name: B, dtype: int64
A C
1st 11 13
2nd 21 23
3rd 31 33
열을 여러 개 선택할 경우에는 리스트의 리스트 형태로 불러와야 한다.
print(df.A)
1st 11
2nd 21
3rd 31
Name: A, dtype: int64
print(df.loc['1st'])
print(df.loc[['1st','3rd']])
A 11
B 12
C 13
Name: 1st, dtype: int64
A B C
1st 11 12 13
3rd 31 32 33
print(df.iloc[0])
print(df.iloc[[0,2]])
print(df.iloc[0:1]])
A 11
B 12
C 13
Name: 1st, dtype: int64
A B C
1st 11 12 13
3rd 31 32 33
A B C
1st 11 12 13
위에서 0부터 셀 때 n번째 행을 선택할 때 사용한다. integer 기반의 슬라이싱을 한다.
df.iloc[:5]
0행부터 4행까지 불러오는 것으로 df.head()와 같다.
df.iloc[:-5]
맨 마지막 5행만 불러올 수 있다. df.tail()과 같다.
데이터프레임의 변수를 이용해 슬라이싱이 가능하다.
데이터 탐색이 다 되었다면 유의미한 데이터를 뽑아내기 위해 슬라이싱을 진행한다.
print(df[df.C<30])
print(df.loc[lambda x: x.C<30])
A B C
1st 11 12 13
2nd 21 22 23
print(df.loc[df['C']<30, ['A','B']])
A B
1st 11 12
2nd 21 22
pandas 데이터프레임은 기본적으로 아래와 같은 데이터프레임 클래스를 가진다.
class pandas.DataFrame(data=None, index=None, columns=None, copy=None)
DataFrame은 크기의 변경이 가능한 2차원 배열이다.(Series는 1차원)
data : ndarray, Iterable, dict, DataFrame
dict에는 Series, 배열 등등 list와 유사한 오브젝트가 올 수 있다.
데이터가 dict인 경우 열(Columns)의 순서는 삽입 순서를 따른다.
index : 인덱스 또는 배열형태의 객체
인스턴스에 설정되는 행 레이블이다. 입력하지 않으면 기본 인덱스가 설정된다. (0, 1, 2, 3...)
columns : 인덱스 또는 배열형태의 객체
인스턴스에 설정되는 열 레이블이다. 입력하지 않으면 기본 인덱스가 설정된다. (0, 1, 2, 3...)
dtype : dtype 데이터 유형을 강제하고자 할때 값이다. 기본값은 None이며 None일경우 type이 자동으로 추론된다.
copy : bool
Ture 일 경우 Dataframe의 원본 데이터를 수정하더라도 인스턴스가 변경되지 않지만
False일 경우 원본데이터를 수정할 시 인스턴스의 값도 바뀌게 된다.
print(df.T)
1st 2nd 3rd
A 11 21 31
B 12 22 32
C 13 23 33
df1 = pd.DataFrame({'A':[11,21,31], 'B':[12,22,32], 'C':[13,23,33]}
, index=['1st','2nd','3rd'])
df2 = pd.DataFrame({'A':[11,21,41], 'B':[12,22,42], 'E':[14,24,44]}
, index=['1st','2nd','4th'])
print(df1+df2)
print(df1 - df2)
print(df1 * df2)
print(df1 / df2)
A B C E
1st 22.0 24.0 NaN NaN
2nd 42.0 44.0 NaN NaN
3rd NaN NaN NaN NaN
4th NaN NaN NaN NaN
A B C E
1st 0.0 0.0 NaN NaN
2nd 0.0 0.0 NaN NaN
3rd NaN NaN NaN NaN
4th NaN NaN NaN NaN
A B C E
1st 121.0 144.0 NaN NaN
2nd 441.0 484.0 NaN NaN
3rd NaN NaN NaN NaN
4th NaN NaN NaN NaN
A B C E
1st 1.0 1.0 NaN NaN
2nd 1.0 1.0 NaN NaN
3rd NaN NaN NaN NaN
4th NaN NaN NaN NaN
값이 있는 것만 계산이 되는 것을 알 수 있다.
df = pd.DataFrame({'A':[11,21,31], 'B':[12,22,32], 'C':[13,23,33]}
, index=['1st','2nd','3rd'])
print(df)
print(df.assign(A_plus_B = df.A+df.B))
A B C
1st 11 12 13
2nd 21 22 23
3rd 31 32 33
A B C A_plus_B
1st 11 12 13 23
2nd 21 22 23 43
3rd 31 32 33 63
print(df.assign(log_A = lambda x:np.log(x.A)))
A B C log_A
1st 11 12 13 2.397895
2nd 21 22 23 3.044522
3rd 31 32 33 3.433987
df.insert(loc=0, column='D', value=[14,24,34])
df.insert(loc=2, column='E', value=5)
print(df)
D A E B C
1st 14 11 5 12 13
2nd 24 21 5 22 23
3rd 34 31 5 32 33
df = df.drop(columns = ['D','E'])
print(df)
A B C
1st 11 12 13
2nd 21 22 23
3rd 31 32 33
df = df.rename(columns = {'A':'aaa'})
print(df)
aaa B C
1st 11 12 13
2nd 21 22 23
3rd 31 32 33
df = pd.DataFrame({'A':[11,21,31], 'B':[12,22,32], 'C':[13,23,33]}
, index=['1st','2nd','3rd'])
df.loc['2nd','A'] = 222
print(df)
A B C
1st 11 12 13
2nd 222 22 23
3rd 31 32 33
df.iloc[:,3] = 'NA'
print(df)
IndexError: iloc cannot enlarge its target object
df = df.replace({'B':32}, 9999)
print(df)
A B C
1st 11 12 13
2nd 21 22 23
3rd 31 9999 33
df = df.sort_values(by='A', ascending=False)
print(df)
기본 정렬은 오름차순(ascending). 내림차순으로 바꾸고 싶다면
ascending = False
을 해주면 된다.
A B C
3rd 31 32 33
2nd 21 22 23
1st 11 12 13
df = df.sort_index(axis=0)
print(df)
A B C
1st 11 12 13
2nd 21 22 23
3rd 31 32 33
df_rank = df.rank(axis=0, method='average', ascending=False)
print(df_rank)
열을 기준으로 평균을 구하고 내림차순으로 구하기
A B C
1st 3.0 3.0 3.0
2nd 2.0 2.0 2.0
3rd 1.0 1.0 1.0
** 순위 구할 때 동점 처리 방법
df = pd.DataFrame({'A' : ['a1', 'a2', 'a3', 'a4'],
'B' : ['b1', 'b2', 'b3', 'b4'],
'C' : [1, 2, 3, 4],
'D' : [100, 200, 300, 400]})
print(df)
A B C D
0 a1 b1 1 100
1 a2 b2 2 200
2 a3 b3 3 300
3 a4 b4 4 400
df_melt = df.melt(id_vars='A', value_vars='B')
print(df_melt)
A variable value
0 a1 B b1
1 a2 B b2
2 a3 B b3
3 a4 B b4
df_melt = df.melt(id_vars = 'A', value_vars='B',
var_name = 'variable', value_name ='value')
print(df_melt)
A variable value
0 a1 B b1
1 a2 B b2
2 a3 B b3
3 a4 B b4
df = pd.DataFrame({'A' : ['a1', 'a2', 'a3', 'a4'],
'B' : ['b1', 'b2', 'b3', 'b4'],
'C' : [1, 2, 3, 4],
'D' : [100, 200, 300, 400]})
print(df.describe())
C D
count 4.000000 4.000000
mean 2.500000 250.000000
std 1.290994 129.099445
min 1.000000 100.000000
25% 1.750000 175.000000
50% 2.500000 250.000000
75% 3.250000 325.000000
max 4.000000 400.000000
A와 B가 문자열이기 때문에 수치형 값에 대해서만 결과를 보여준다
df = pd.DataFrame({'A':[11,21,31,None,31], 'B':[12,22,32,42,32], 'C':[13,None,33,43,33]}
, index=['1st','2nd','3rd','4th','7th'])
print(df)
A B C
1st 11.0 12 13.0
2nd 21.0 22 NaN
3rd 31.0 32 33.0
4th NaN 42 43.0
7th 31.0 32 33.0
print(df.drop_duplicates())
A B C
1st 11.0 12 13.0
2nd 21.0 22 NaN
3rd 31.0 32 33.0
4th NaN 42 43.0
print(df.dropna())
A B C
1st 11.0 12 13.0
3rd 31.0 32 33.0
7th 31.0 32 33.0
print(df.fillna(method = 'ffill')) # df = df.fillna(method = 'pad')
A B C
1st 11.0 12 13.0
2nd 21.0 22 13.0
3rd 31.0 32 33.0
4th 31.0 42 43.0
7th 31.0 32 33.0
print(df.fillna(method = 'bfill')) # df = df.fillna(method = 'backfill')
A B C
1st 11.0 12 13.0
2nd 21.0 22 33.0
3rd 31.0 32 33.0
4th 31.0 42 43.0
7th 31.0 32 33.0
데이터를 필터링하는 함수.
특정 조건에 맞는 칼럼이나 행을 선택해 가져오기.
df = pd.DataFrame(
np.arange(12).reshape(3, 4),
index=['abc', 'bbb', 'ccc'],
columns=['x_1', 'x_2', 'var1', 'var2'])
print(df)
x_1 x_2 var1 var2
abc 0 1 2 3
bbb 4 5 6 7
ccc 8 9 10 11
print(df.filter(items=['x_1', 'var2'], axis=1))
x_1 var2
abc 0 3
bbb 4 7
ccc 8 11
print(df.filter(items=['bbb', 'ccc'], axis = 0))
x_1 x_2 var1 var2
bbb 4 5 6 7
ccc 8 9 10 11
print(df.filter(regex='^(x_).+', axis=1))
x_1 x_2
abc 0 1
bbb 4 5
ccc 8 9
print(df.filter(like='x_', axis=1)) #특정 문자 포함하는 column 가져오기
x_1 x_2
abc 0 1
bbb 4 5
ccc 8 9
조건에 부합하는 데이터 추출할 때 사용
장점: 가독성과 편의성
단점: .loc[ ]로 구현한 것보다 속도가 느리다
df = pd.DataFrame({"age": [10, 10, 21, 22], "weight": [20, 30, 60, 70]})
print(df)
age weight
0 10 20
1 10 30
2 21 60
3 22 70
1) 비교 연산자( ==, >, >=, <, <=, != )
df_q = df.query("age != 10")
print(df_q)
age weight
2 21 60
3 22 70
2) in 연산자( in, ==, not in, != )
df_q = df.query("age in [21, 22]") # 나이가 21 또는 22이다
print(df_q)
age weight
2 21 60
3 22 70
3) 논리 연산자(and, or, not)
df_q = df.query("(age == 10) and (weight >= 30)") # 나이가 10이고 몸무게가 30kg 이상이다
print(df_q)
age weight
1 10 30
4) 외부 변수(또는 함수) 참조 연산
외부 변수명 또는 함수명 앞에 @를 붙여 사용한다.
만약 존재하지 않은 변수명을 기입하면 UndefinedVariableError 오류가 발생한다.
num_age = 10
num_weight = 30
df_q = df.query("(age == @num_age) and (weight >= @num_weight)")
print(df_q)
age weight
1 10 30
5) 인덱스 검색
df_q = df.query("index >= 2" ) # 인덱스가 2이상인 데이터
print(df_q)
age weight
2 21 60
3 22 70
데이터를 그룹별로 분할하여 독립된 그룹에 대해 별도로 데이터를 처리하거나 그룹별 통계량을 확인하려고 할 때 유용하다.
.groupby() 함수 사용
import seaborn as sns
df = sns.load_dataset('tips')
print(df.head())
total_bill tip sex smoker day time size
0 16.99 1.01 Female No Sun Dinner 2
1 10.34 1.66 Male No Sun Dinner 3
2 21.01 3.50 Male No Sun Dinner 3
3 23.68 3.31 Male No Sun Dinner 2
4 24.59 3.61 Female No Sun Dinner 4
day 별로 그룹을 나누어 total bill의 평균을 구하기
data_s = df.groupby(by='day')['total_bill'].mean()
print(data_s)
print(type(data_s)) # Series 데이터
print(data_s.index)
print(data_s.values)
day
Thur 17.682742
Fri 17.151579
Sat 20.441379
Sun 21.410000
Name: total_bill, dtype: float64
<class 'pandas.core.series.Series'>
CategoricalIndex(['Thur', 'Fri', 'Sat', 'Sun'], categories=['Thur', 'Fri', 'Sat', 'Sun'], ordered=False, dtype='category', name='day')
[17.68274194 17.15157895 20.44137931 21.41 ]
액셀의 매크로 함수처럼 각 열에 대한 연산을 하는 함수.
df = pd.DataFrame('A':[1, 2, 3], 'B':[4, 5, 6], 'C':[7, 8, 9] })
print(df)
A B C
0 1 4 7
1 2 5 8
2 3 6 9
add column과 mean column을 apply()로 추가하기
df = df.apply(np.sum, axis = 0)
print(df)
A 6
B 15
C 24
dtype: int64
df1 = pd.DataFrame({'id':['1st','2nd','3rd'], 'name': ['홍길동', '임꺽정', '김홍익']})
df2 = pd.DataFrame({'id':['2nd','3rd','4th'], 'address': ['서울', '강원도', '경기도']})
print(df1)
print(df2)
id name
0 1st 홍길동
1 2nd 임꺽정
2 3rd 김홍익
id address
0 2nd 서울
1 3rd 강원도
2 4th 경기도
inner_join = pd.merge(df1, df2, on='id', how='inner')
outer_join = pd.merge(df1, df2, on='id', how='outer')
print('inner: \n', inner_join)
print('outer: \n', outer_join)
inner:
id name address
0 2nd 임꺽정 서울
1 3rd 김홍익 강원도
outer:
id name address
0 1st 홍길동 NaN
1 2nd 임꺽정 서울
2 3rd 김홍익 강원도
3 4th NaN 경기도
left_join = pd.merge(df1, df2, on='id', how='left')
right_join = pd.merge(df1, df2, on='id', how='right')
print('left: \n', left_join)
print('right: \n', right_join)
left:
id name address
0 1st 홍길동 NaN
1 2nd 임꺽정 서울
2 3rd 김홍익 강원도
right:
id name address
0 2nd 임꺽정 서울
1 3rd 김홍익 강원도
2 4th NaN 경기도
df = pd.DataFrame({'name':['Kim','Lee','Park','Kim','Lee','Kim']
, 'sex':['M','F','F','M','F','M']
, 'age':[20,25,30,20,25,20]
, 'class':['DS','DS','DS','PP','PP','DV']})
print(df)
name sex age class
0 Kim M 20 DS
1 Lee F 25 DS
2 Park F 30 DS
3 Kim M 20 PP
4 Lee F 25 PP
5 Kim M 20 DV
print(df.groupby(by='class')['name'].count())
class
DS 3
DV 1
PP 2
Name: name, dtype: int64
df_mean_age = (df
.groupby(by=['name','sex','age'])
.filter(lambda x: len(x)>=2)[['name','age']]
.drop_duplicates()['age']
.mean())
print(df_mean_age)
22.5
pandas는 plot이라는 시각화 메서드를 내장하고 있다. Plot은 Matplotlib을 내부에서 import해서 사용한다.
np.random.seed(0)
df1 = pd.DataFrame(np.random.randn(100, 3),
index=pd.date_range('1/1/2018', periods=100),
columns=['A', 'B', 'C']).cumsum()
print(df1.tail())
A B C
2018-04-06 9.396256 6.282026 -11.198087
2018-04-07 10.086074 7.583872 -11.826175
2018-04-08 9.605047 9.887789 -12.886190
2018-04-09 9.469097 11.024680 -12.788465
2018-04-10 10.052051 10.625231 -12.418409
import matplotlib.pyplot as plt
df1.plot()
plt.title("Pandas의 Plot메소드 사용 예")
plt.xlabel("시간")
plt.ylabel("Data")
plt.show()

df.plot(kind = 'barh')
