1. 판다스(Pandas) 기초(1) 요약
1.1 판다스(Pandas) 기초(1) summary
- 데이터 분석 : 데이터 전처리 파트에서 많이 사용하는 패키지
- 테이블 형테의 데이터를 처리할때 사용하는 python 라이브러리
- Series : index, value 로 이루어지며, 한가지 데이터 타입만 가질수 있음
- 생성, 선택, 수정 방법
- DataFrame : index, value, column으로 이루어지며 Series들의 집합
- 생성 방법 1 : 딕셔너리의 리스트 {[],[]} -> 리스트 -> 컬럼 데이터
- 생성 방법 2 : 리스트의 딕셔너리[{},{}] -> 딕셔너리 -> 로우 데이터
- row 선택 : df.loc[idx]
- column 선택 : df[column name]
- row, column 선택 : df.loc[idx, column]
- 함수
- apply, append, concat,
- groupby, merge
1.2 quiz
1.2.1 makedata 모듈을 이용해서 데이터 프레임 만들기
- makedata 모듈은 따로 만든거라 파이썬 기본패키지에는 없는것
- user_df
- 8명의 데이터
- UserID
- Name : makedata.get_name()
- Age : makedata.get_age()
- 중복되는 Name 값이 없도록
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import makedata
datas = {}
datas['UserID'] = list(range(1, 9))
datas['Age'] = [makedata.get_age() for i in range(8)]
names = []
while True:
name = makedata.get_name()
if name not in names:
names.append(name)
if len(names) == 8:
break
datas['Name'] = names
user_df = pd.DataFrame(datas)
user_df
UserID | Age | Name | |
---|---|---|---|
0 | 1 | 30 | Alan |
1 | 2 | 30 | Alvin |
2 | 3 | 30 | Andrew |
3 | 4 | 25 | Arnold |
4 | 5 | 31 | Anthony |
5 | 6 | 29 | Billy |
6 | 7 | 32 | Anchal |
7 | 8 | 21 | Alex |
- 딕셔너리 안에 리스트 형식으로 생성
- not in을 사용하여 없는 이름만 names에 append 시킴
- 이후 names의 길이가 8이되면 break를 사용하여 멈춤
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
user_df = pd.DataFrame(columns=['UserID', 'Name', 'Age'])
datas = []
for idx in range(1, 9):
name = makedata.get_name()
while name in list(user_df['Name']):
name = makedata.get_name()
data = {'Name':name, 'UserID' : idx , 'Age' : makedata.get_age()}
user_df.loc[len(user_df)] = data
datas.append(data)
user_df
UserID | Name | Age | |
---|---|---|---|
0 | 1 | Alan | 26 |
1 | 2 | Arnold | 37 |
2 | 3 | Billy | 39 |
3 | 4 | Alvin | 31 |
4 | 5 | Jin | 26 |
5 | 6 | Andrew | 21 |
6 | 7 | Anchal | 27 |
7 | 8 | Anthony | 38 |
- 리스트안에 딕셔너리로 만듬
- 딕셔너리로 맨 마지막 행을 넣는 법
- loc[] 에 idx를 넣어야 하는데
- loc[len(user_df)]를 하면 user_df 갯수의 인덱스에 생성된 데이터가 들어감
1.2.2 money_df 만들기
- 15개의 데이터가 있습니다.
- ID : 1 ~ 8 까지의 랜덤한 숫자 데이터
- Money : 1000원 단위로 1000원 ~ 20000원 까지의 숫자가 저장
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 딕셔너리 데이터를 데이터 프레임에 하나씩 추가
money_df = pd.DataFrame(columns=['ID', 'Money'])
np.random.randint(1, 9)
for i in range(15):
money_df.loc[len(money_df)] = {
'ID': np.random.randint(1, 9),
'Money': np.random.randint(1, 21) * 100
}
# 컬럼 데이터에서 Unique값 확인
ids = money_df['ID'].unique()
ids.sort()
ids
1
array([1, 2, 4, 5, 6, 8], dtype=object)
1
money_df.tail(1)
ID | Money | |
---|---|---|
14 | 1 | 1200 |
1
user_df.tail(1)
UserID | Name | Age | |
---|---|---|---|
7 | 8 | Anthony | 38 |
2. 판다스(Pandas) 기초(2)
2.1 Inner Merge(inner join)
1
user_df.merge(money_df, left_on='UserID', right_on='ID')
UserID | Name | Age | ID | Money | |
---|---|---|---|---|---|
0 | 1 | Alan | 26 | 1 | 1200 |
1 | 1 | Alan | 26 | 1 | 200 |
2 | 1 | Alan | 26 | 1 | 1200 |
3 | 2 | Arnold | 37 | 2 | 1600 |
4 | 2 | Arnold | 37 | 2 | 1500 |
5 | 2 | Arnold | 37 | 2 | 200 |
6 | 2 | Arnold | 37 | 2 | 1100 |
7 | 4 | Alvin | 31 | 4 | 200 |
8 | 4 | Alvin | 31 | 4 | 900 |
9 | 5 | Jin | 26 | 5 | 900 |
10 | 6 | Andrew | 21 | 6 | 700 |
11 | 8 | Anthony | 38 | 8 | 1700 |
12 | 8 | Anthony | 38 | 8 | 100 |
13 | 8 | Anthony | 38 | 8 | 1100 |
14 | 8 | Anthony | 38 | 8 | 500 |
- 1 : 1로 테이블을 만든 뒤 같은 데이터들 끼리 필터링 해줌
- merge메소드는 inner 옵션이 디폴트라, 따로 how = ‘inner’ 를 적지않아도됨
1
2
user_df.rename(columns={'UserID' : 'ID'}, inplace = True)
user_df.tail(1)
ID | Name | Age | |
---|---|---|---|
7 | 8 | Anthony | 38 |
- 컬럼명 변경은 columns 옵션을 사용한다
1
user_df.merge(money_df).tail(2)
ID | Name | Age | Money | |
---|---|---|---|---|
13 | 8 | Anthony | 38 | 1100 |
14 | 8 | Anthony | 38 | 500 |
- 컬럼명이 동일하면 left_on, right_on 설정을 안해주어도 된다.
1
2
result_df = pd.merge(money_df, user_df)
result_df.tail(2)
ID | Money | Name | Age | |
---|---|---|---|---|
13 | 4 | 200 | Alvin | 31 |
14 | 4 | 900 | Alvin | 31 |
- pd.객체의 merge함수를 사용하여 생성 가능
- merge(df1, df2)는 작성한 순서에 따라 merge됨
1
2
money_lis = result_df.groupby('Name').sum()['Money'].reset_index()
money_lis
Name | Money | |
---|---|---|
0 | Alan | 2600 |
1 | Alvin | 1100 |
2 | Andrew | 700 |
3 | Anthony | 3400 |
4 | Arnold | 4400 |
5 | Jin | 900 |
- groupby : sum, size, min .. 함수를 사용하여 그룹바이 해줌, Series
- inner merge 이기에 없든 데이터는 merge가 되지 않음
- Series 이기에 더해주는 값 등은 1개만 올수있음 ex) money
1
2
money_list = result_df.groupby("Name").agg("sum").reset_index()[['Name', 'Money']]
money_list
Name | Money | |
---|---|---|
0 | Alan | 2600 |
1 | Alvin | 1100 |
2 | Andrew | 700 |
3 | Anthony | 3400 |
4 | Arnold | 4400 |
5 | Jin | 900 |
- groupby : agg(“sum”), agg(“mean”), … : DataFrame
- 데이터프레임이기에 더해주는 값은 여러개 가능함 money뒤에 “Age” 넣어주면됨
2.2 Outer Merge
1
2
result = pd.merge(user_df, money_list, how = 'outer')
result
ID | Name | Age | Money | |
---|---|---|---|---|
0 | 1 | Alan | 26 | 2600.0 |
1 | 2 | Arnold | 37 | 4400.0 |
2 | 3 | Billy | 39 | NaN |
3 | 4 | Alvin | 31 | 1100.0 |
4 | 5 | Jin | 26 | 900.0 |
5 | 6 | Andrew | 21 | 700.0 |
6 | 7 | Anchal | 27 | NaN |
7 | 8 | Anthony | 38 | 3400.0 |
- Outer Join으로 없는 데이터도 조인이 되게 할수 있음
- Money에 보면 NaN값이 있다. Outer Join이 되어 결측치가 생김
2.2.1 Fillna
1
2
result.fillna(value = 0, inplace = True)
result
ID | Name | Age | Money | |
---|---|---|---|---|
0 | 1 | Alan | 26 | 2600.0 |
1 | 2 | Arnold | 37 | 4400.0 |
2 | 3 | Billy | 39 | 0.0 |
3 | 4 | Alvin | 31 | 1100.0 |
4 | 5 | Jin | 26 | 900.0 |
5 | 6 | Andrew | 21 | 700.0 |
6 | 7 | Anchal | 27 | 0.0 |
7 | 8 | Anthony | 38 | 3400.0 |
- fillna : NaN을 특정 데이터로 채워줌 (결측치 처리)
- fillna를 사용하여 결측치를 0으로 만들수 있음
- 데이터 프레임을 연산하는 과정을 거치면 실수타입으로 변환이 됨
1
result.dtypes
1
2
3
4
5
ID int64
Name object
Age int64
Money float64
dtype: object
1
2
result['Money'] = result['Money'].astype('int')
result
ID | Name | Age | Money | |
---|---|---|---|---|
0 | 1 | Alan | 26 | 2600 |
1 | 2 | Arnold | 37 | 4400 |
2 | 3 | Billy | 39 | 0 |
3 | 4 | Alvin | 31 | 1100 |
4 | 5 | Jin | 26 | 900 |
5 | 6 | Andrew | 21 | 700 |
6 | 7 | Anchal | 27 | 0 |
7 | 8 | Anthony | 38 | 3400 |
- money컬럼을 정수 데이터 타입으로 변경
1
result.sort_values('Money', ascending= False)
ID | Name | Age | Money | |
---|---|---|---|---|
1 | 2 | Arnold | 37 | 4400 |
7 | 8 | Anthony | 38 | 3400 |
0 | 1 | Alan | 26 | 2600 |
3 | 4 | Alvin | 31 | 1100 |
4 | 5 | Jin | 26 | 900 |
5 | 6 | Andrew | 21 | 700 |
2 | 3 | Billy | 39 | 0 |
6 | 7 | Anchal | 27 | 0 |
- money가 많은 사람으로 순으로 정렬 (내림차순)
1
np.average(result.sort_values('Money', ascending= False)[:3]['Money'])
1
3466.6666666666665
- 상위 3명의 평균값을 np.average와 sort, offset index을 활용하여 계산하였다