DataFrame 데이터 조작
출처 : https://pandas.pydata.org/pandas-docs/stable/reference/frame.html
데이터 변경
데이터를 선택하는 다양한 방법이 있었다. 데이터변경은 선택한 데이터에 새로운 값을 넣어주면 된다.
columns을 선택한 후, 데이터의 갯수에 맞는 Series나 list를 입력하면 columns의 값이 바뀌고, 만약 없는 column 이름에 새로운 데이터를 넣으면 새로운 column이 추가된다.
마찬가지로 columns 전체가 아니라 loc, iloc, at, iat 등으로 선택한 각 위치의 값들도 모두 변경해 줄 수 있다.
1. column 값 전체 변경하기
기존 값 변경 - 존재하는 column 이름
data['국어'] = ['A','B','C','A','B','C','A','B','C','A','B','C','A','B','C','A']
새로운 값 추가 - 새로운 column 이름
data['group'] = ['A','B','C','A','B','C','A','B','C','A','B','C','A','B','C','A']
|
data['국어'] = ['A','B','C','A','B','C','A','B','C','A','B','C','A','B','C','A']
print(data)
data['group'] = ['A','B','C','A','B','C','A','B','C','A','B','C','A','B','C','A']
print(data)
|
결과
|
번호 국어 영어 수학 과학
0 1번 A 56 65 45
1 2번 B 95 98 95
2 3번 C 65 54 68
3 4번 A 95 68 78
4 5번 B 85 75 95
5 6번 C 75 95 45
6 7번 A 65 84 95
7 8번 B 68 92 65
8 9번 C 94 34 84
9 10번 A 51 68 95
10 11번 B 67 95 68
11 12번 C 84 78 79
12 13번 A 92 95 45
13 14번 B 65 64 92
14 15번 C 78 95 68
15 16번 A 65 46 94
번호 국어 영어 수학 과학 group
0 1번 A 56 65 45 A
1 2번 B 95 98 95 B
2 3번 C 65 54 68 C
3 4번 A 95 68 78 A
4 5번 B 85 75 95 B
5 6번 C 75 95 45 C
6 7번 A 65 84 95 A
7 8번 B 68 92 65 B
8 9번 C 94 34 84 C
9 10번 A 51 68 95 A
10 11번 B 67 95 68 B
11 12번 C 84 78 79 C
12 13번 A 92 95 45 A
13 14번 B 65 64 92 B
14 15번 C 78 95 68 C
15 16번 A 65 46 94 A
|
2. 특정 위치 값 변경하기
특정 위치 값을 찾아서 새로운 값을 입력해주면 된다.
1) 한개 값 변경
data.at[0, '국어'] = 100
2) 여러 개 rows 값 변경
data.loc[1:3, '국어'] = [10, 25, 34]
|
data.at[0, '국어'] = 100
data.loc[1:3, '국어'] = [10, 25, 34]
print(data)
|
결과
|
번호 국어 영어 수학 과학 group
0 1번 100 56 65 45 A
1 2번 10 95 98 95 B
2 3번 25 65 54 68 C
3 4번 34 95 68 78 A
4 5번 B 85 75 95 B
5 6번 C 75 95 45 C
6 7번 A 65 84 95 A
7 8번 B 68 92 65 B
8 9번 C 94 34 84 C
9 10번 A 51 68 95 A
10 11번 B 67 95 68 B
11 12번 C 84 78 79 C
12 13번 A 92 95 45 A
13 14번 B 65 64 92 B
14 15번 C 78 95 68 C
15 16번 A 65 46 94 A
|
3) 여러 개의 rows, columns 값 변경
data.loc[0:3, ['수학','과학']] = [[10,10], [20,20], [30,30], [40,40]]
|
print(data.loc[0:3, ['수학','과학']])
data.loc[0:3, ['수학','과학']] = [[10,10], [20,20], [30,30], [40,40]]
print(data)
|
결과
|
수학 과학
0 65 45
1 98 95
2 54 68
3 68 78
번호 국어 영어 수학 과학 group
0 1번 100 56 10 10 A
1 2번 B 95 20 20 B
2 3번 C 65 30 30 C
3 4번 A 95 40 40 A
4 5번 B 85 75 95 B
5 6번 C 75 95 45 C
6 7번 A 65 84 95 A
7 8번 B 68 92 65 B
8 9번 C 94 34 84 C
9 10번 A 51 68 95 A
10 11번 B 67 95 68 B
11 12번 C 84 78 79 C
12 13번 A 92 95 45 A
13 14번 B 65 64 92 B
14 15번 C 78 95 68 C
15 16번 A 65 46 94 A
|
다양한 위치의 값을 찾아서 변경하는 연습을 해본다.
3. drop() - rows 또는 columns 삭제
rows또는 coumns를 삭제하는 메서드는 drop()이다.
axis argument는 row또는 column을 선택한다. drop(list, axis) 메서드를 사용했을 시, 결과는 새로운 DataFrame으로 저장한다.
axis = 0 : rows (default)
axis = 1 : columns
data = data.drop(0)
data = data.drop([5, 7])
data = data.drop('국어', axis = 1)
data = data.drop(['영어','수학'], axis = 1)
|
data = data.drop(0)
data = data.drop([5, 7])
print(data)
data = data.drop('국어', axis = 1)
data = data.drop(['영어','수학'], axis = 1)
print(data)
|
결과
|
번호 국어 영어 수학 과학 group
1 2번 B 95 20 20 B
2 3번 C 65 30 30 C
3 4번 A 95 40 40 A
4 5번 B 85 75 95 B
6 7번 A 65 84 95 A
8 9번 C 94 34 84 C
9 10번 A 51 68 95 A
10 11번 B 67 95 68 B
11 12번 C 84 78 79 C
12 13번 A 92 95 45 A
13 14번 B 65 64 92 B
14 15번 C 78 95 68 C
15 16번 A 65 46 94 A
번호 과학 group
1 2번 20 B
2 3번 30 C
3 4번 40 A
4 5번 95 B
6 7번 95 A
8 9번 84 C
9 10번 95 A
10 11번 68 B
11 12번 79 C
12 13번 45 A
13 14번 92 B
14 15번 68 C
15 16번 94 A
|
drop()으로 삭제한 rows의 index를 보면 삭제된 index가 그대로 유지된다. 따라서 index를 재 정렬하기 위해서는 reset_index(drop=True) 메서드를 사용한다.
drop을 False(default)로 설정하면 기존 index가 index라는 column 이름으로 새로운 column이 생기게 된다.
|
data = data.reset_index(drop=True)
print(data)
|
결과
|
번호 과학 group
0 2번 20 B
1 3번 30 C
2 4번 40 A
3 5번 95 B
4 7번 95 A
5 9번 84 C
6 10번 95 A
7 11번 68 B
8 12번 79 C
9 13번 45 A
10 14번 92 B
11 15번 68 C
12 16번 94 A
|
4. pop()으로 column 결과를 얻고 삭제하기
pop(column) 메서드를 이용하면, 입력한 column의 내용을 Series로 반환하고 그 column은 삭제된다. drop() 처럼 원본이 남지 않고, DataFrame에 바로 반영되기 때문에 pop()한 결과물은 따로 저장해두는 것이 좋다.
|
column_eng = data.pop('영어')
print(column_eng)
print(data)
|
결과
|
0 56
1 95
2 65
3 95
4 85
5 75
6 65
7 68
8 94
9 51
10 67
11 84
12 92
13 65
14 78
15 65
Name: 영어, dtype: int64
번호 국어 수학 과학
0 1번 70 65 45
1 2번 65 98 95
2 3번 80 54 68
3 4번 68 68 78
4 5번 95 75 95
5 6번 62 95 45
6 7번 35 84 95
7 8번 78 92 65
8 9번 56 34 84
9 10번 50 68 95
10 11번 64 95 68
11 12번 89 78 79
12 13번 65 95 45
13 14번 59 64 92
14 15번 32 95 68
15 16번 21 46 94
|
pop()으로 return된 결과는 Series이다. Series는 values와 name을 갖는다.
저장된 column_eng를 다시 data에 입력해본다.
|
data[column_eng.name] = column_eng.values
print(data)
|
결과
|
번호 국어 수학 과학 영어
0 1번 70 65 45 56
1 2번 65 98 95 95
2 3번 80 54 68 65
3 4번 68 68 78 95
4 5번 95 75 95 85
5 6번 62 95 45 75
6 7번 35 84 95 65
7 8번 78 92 65 68
8 9번 56 34 84 94
9 10번 50 68 95 51
10 11번 64 95 68 67
11 12번 89 78 79 84
12 13번 65 95 45 92
13 14번 59 64 92 65
14 15번 32 95 68 78
15 16번 21 46 94 65
|
5. insert()로 columns 입력하기
insert() 메서드를 통해 column을 원하는 위치에 삽입할 수 있다. 삽입된 결과는 DataFrame에 바로 적용된다.
DataFrame.insert(self, loc, column, value, allow_duplicates=False)
loc은 column이 들어갈 위치이며, 0에서 column의 갯수의 범위안에서 설정한다. over하면 error 발생
만약, allow_duplicates가 False이고 column 이름이 중복이면 ValueError가 발생한다.
|
data.insert(0, column_eng.name, column_eng.values)
print(data)
|
결과
|
영어 번호 국어 수학 과학
0 56 1번 70 65 45
1 95 2번 65 98 95
2 65 3번 80 54 68
3 95 4번 68 68 78
4 85 5번 95 75 95
5 75 6번 62 95 45
6 65 7번 35 84 95
7 68 8번 78 92 65
8 94 9번 56 34 84
9 51 10번 50 68 95
10 67 11번 64 95 68
11 84 12번 89 78 79
12 92 13번 65 95 45
13 65 14번 59 64 92
14 78 15번 32 95 68
15 65 16번 21 46 94
|
6. Missing Data(결측치) 처리
프로그래밍에서는 데이터가 들어있지 않는 결과를 None, Null 등으로 표현한다. 이러한 값은 연산이나 통계를 처리할 수 없어서 Missing Data(결측값)라고 한다.
pandas에서 Missing Data는 NaN으로 표현하는데 이는 numpy.nan의 표현 방법이다. 따라서 DataFrame의 value가 NaN일 경우를 판단하는 코드는 if numpy.isnan(A): 또는 if pandas.isna(A):식으로 만들면 된다.
* 작성한 DataFrame에서 결측치가 한개라도 있는 행들을 삭제하고 싶을 때는 DataFrame.dropna() 메서드를 사용한다.
* 결측치가 있는 행을 버리지 않고, 결측치를 다른 값으로 변경하고 싶을 때는 DataFrame.fillna(value) 메서드를 사용한다.
* 해당 값이 NaN인지 확인할 때는 pd.isna() 메서드를 사용한다.
datasample.xlsx 파일의 몇 군데 값을 삭제하고 테스트 해본다.
1) 결측된 데이터 보기
|
print(data)
print(pd.isna(data))
|
결과
|
번호 국어 영어 수학 과학
0 1번 70.0 56.0 65.0 45
1 2번 NaN 95.0 98.0 95
2 3번 80.0 65.0 54.0 68
3 4번 68.0 95.0 68.0 78
4 5번 95.0 NaN 75.0 95
5 6번 62.0 75.0 95.0 45
6 7번 35.0 65.0 84.0 95
7 8번 78.0 68.0 92.0 65
8 9번 56.0 94.0 NaN 84
9 10번 50.0 51.0 68.0 95
10 11번 64.0 67.0 95.0 68
11 12번 89.0 84.0 78.0 79
12 13번 65.0 92.0 95.0 45
13 14번 59.0 65.0 64.0 92
14 15번 32.0 78.0 95.0 68
15 16번 21.0 65.0 46.0 94
번호 국어 영어 수학 과학
0 False False False False False
1 False True False False False
2 False False False False False
3 False False False False False
4 False False True False False
5 False False False False False
6 False False False False False
7 False False False False False
8 False False False True False
9 False False False False False
10 False False False False False
11 False False False False False
12 False False False False False
13 False False False False False
14 False False False False False
15 False False False False False
|
2) 결측된 데이터 삭제 - NaN 값이 있는 row 전체 삭제
|
data = data.dropna()
print(data)
|
결과
|
번호 국어 영어 수학 과학
0 1번 70.0 56.0 65.0 45
2 3번 80.0 65.0 54.0 68
3 4번 68.0 95.0 68.0 78
5 6번 62.0 75.0 95.0 45
6 7번 35.0 65.0 84.0 95
7 8번 78.0 68.0 92.0 65
9 10번 50.0 51.0 68.0 95
10 11번 64.0 67.0 95.0 68
11 12번 89.0 84.0 78.0 79
12 13번 65.0 92.0 95.0 45
13 14번 59.0 65.0 64.0 92
14 15번 32.0 78.0 95.0 68
15 16번 21.0 65.0 46.0 94
|
3) 결측된 데이터 변경하기
|
data = data.fillna(value=100)
print(data)
|
결과
|
번호 국어 영어 수학 과학
0 1번 70.0 56.0 65.0 45
1 2번 100.0 95.0 98.0 95
2 3번 80.0 65.0 54.0 68
3 4번 68.0 95.0 68.0 78
4 5번 95.0 100.0 75.0 95
5 6번 62.0 75.0 95.0 45
6 7번 35.0 65.0 84.0 95
7 8번 78.0 68.0 92.0 65
8 9번 56.0 94.0 100.0 84
9 10번 50.0 51.0 68.0 95
10 11번 64.0 67.0 95.0 68
11 12번 89.0 84.0 78.0 79
12 13번 65.0 92.0 95.0 45
13 14번 59.0 65.0 64.0 92
14 15번 32.0 78.0 95.0 68
15 16번 21.0 65.0 46.0 94
|
7. 지정한 값을 다른 데이터를 변경
DataFrame.replace() 메서드를 통해 설정한 값을 다른 값으로 변경할 수 있다.
DataFrame.replace(self, to_replace=None, value=None, inplace=False, limit=None, regex=False, method='pad')
만약 결측값을 변경하고 싶다면 아래와 같이 한다.
|
data = data.replace(np.nan, 100)
print(data)
|
결과
|
번호 국어 영어 수학 과학
0 1번 70.0 56.0 65.0 45
1 2번 100.0 95.0 98.0 95
2 3번 80.0 65.0 54.0 68
3 4번 68.0 95.0 68.0 78
4 5번 95.0 100.0 75.0 95
5 6번 62.0 75.0 95.0 45
6 7번 35.0 65.0 84.0 95
7 8번 78.0 68.0 92.0 65
8 9번 56.0 94.0 100.0 84
9 10번 50.0 51.0 68.0 95
10 11번 64.0 67.0 95.0 68
11 12번 89.0 84.0 78.0 79
12 13번 65.0 92.0 95.0 45
13 14번 59.0 65.0 64.0 92
14 15번 32.0 78.0 95.0 68
15 16번 21.0 65.0 46.0 94
|
replace() 메서드는 결측값만 변경하는 것이 아니라 변경하고 싶은 값은 어떤 것이건 대입할 수 있으므로 다양하게 사용할 수 있다.
8. 함수를 사용한 값 변경
DataFrame.apply() 메서드를 통해 함수를 적용할 수 있다.
DataFrame.apply(self, func, axis=0, raw=False, result_type=None, args=(), **kwds)
만약 수학 점수에 따라 등급을 A, B, C로 나누고 싶다면 아래와 같이 작성할 수 있다.
|
def func(row):
if row > 90:
return 'A'
elif row > 80:
return 'B'
else:
return 'C'
data['수학'] = data['수학'].apply(func)
print(data)
|
결과
|
번호 국어 영어 수학 과학
0 1번 70 56 C 45
1 2번 65 95 A 95
2 3번 80 65 C 68
3 4번 68 95 C 78
4 5번 95 85 C 95
5 6번 62 75 A 45
6 7번 35 65 B 95
7 8번 78 68 A 65
8 9번 56 94 C 84
9 10번 50 51 C 95
10 11번 64 67 A 68
11 12번 89 84 C 79
12 13번 65 92 A 45
13 14번 59 65 C 92
14 15번 32 78 A 68
15 16번 21 65 C 94
|
하지만 위의 방법으로 하면 수학값이 모두 A, B, C로 바뀌어 원래 점수를 알 수 없게 된다.
따라서 변경된 값을 다른 column으로 저장을 한다면, 원본 값을 유지할 수 있다.
|
def func(row):
if row > 90:
return 'A'
elif row > 80:
return 'B'
else:
return 'C'
data['Grade'] = data['수학'].apply(func)
print(data)
|
결과
|
번호 국어 영어 수학 과학 Grade
0 1번 70 56 65 45 C
1 2번 65 95 98 95 A
2 3번 80 65 54 68 C
3 4번 68 95 68 78 C
4 5번 95 85 75 95 C
5 6번 62 75 95 45 A
6 7번 35 65 84 95 B
7 8번 78 68 92 65 A
8 9번 56 94 34 84 C
9 10번 50 51 68 95 C
10 11번 64 67 95 68 A
11 12번 89 84 78 79 C
12 13번 65 92 95 45 A
13 14번 59 65 64 92 C
14 15번 32 78 95 68 A
15 16번 21 65 46 94 C
|
특정 칼럼을 선택해서 function을 적용하는 것이 아니라 data전체를 apply()할 때는 func내에서 row[column] 값을 지정해주면 된다. 그리고 apply() 메소드의 axis 속성을 1로 설정한다.
아래 코드의 결과는 위와 같다.
|
def func(row):
if row['수학'] > 90:
return 'A'
elif row['수학'] > 80:
return 'B'
else:
return 'C'
data['Grade2'] = data.apply(func, axis = 1)
print(data)
|
결과
|
번호 국어 영어 수학 과학 Grade2
0 1번 70 56 65 45 C
1 2번 65 95 98 95 A
2 3번 80 65 54 68 C
3 4번 68 95 68 78 C
4 5번 95 85 75 95 C
5 6번 62 75 95 45 A
6 7번 35 65 84 95 B
7 8번 78 68 92 65 A
8 9번 56 94 34 84 C
9 10번 50 51 68 95 C
10 11번 64 67 95 68 A
11 12번 89 84 78 79 C
12 13번 65 92 95 45 A
13 14번 59 65 64 92 C
14 15번 32 78 95 68 A
15 16번 21 65 46 94 C
|
data 전체를 apply() 메서드로 적용시킬때, row는 행 전체를 의미한다. 따라서 여러개의 column을 이용하여 조건을 다양하게 만들 수 있다.
|
def func(row):
if row['수학'] > 90 and row['국어'] > 90:
return 'A'
elif row['수학'] > 80 and row['국어'] > 80:
return 'B'
else:
return 'C'
data['Grade2'] = data.apply(func, axis = 1)
print(data)
|
apply() 메서드의 function을 lamda로 처리할 수도 있다.
|
data['Grade3'] = data['수학'].apply(lambda x: 'A' if x > 90 else 'B' if x > 80 else 'C')
print(data)
|
결과
|
번호 국어 영어 수학 과학 Grade3
0 1번 70 56 65 45 C
1 2번 65 95 98 95 A
2 3번 80 65 54 68 C
3 4번 68 95 68 78 C
4 5번 95 85 75 95 C
5 6번 62 75 95 45 A
6 7번 35 65 84 95 B
7 8번 78 68 92 65 A
8 9번 56 94 34 84 C
9 10번 50 51 68 95 C
10 11번 64 67 95 68 A
11 12번 89 84 78 79 C
12 13번 65 92 95 45 A
13 14번 59 65 64 92 C
14 15번 32 78 95 68 A
15 16번 21 65 46 94 C
|
8. append() - row 추가
append() 메서드는 row를 추가하는 기능을 한다.
DataFrame.append(self, other, ignore_index=False, verify_integrity=False, sort=False)
other : DataFrame 또는 Series/dictionary, list
ignore_index = False : other가 가지고 있던 index가 유지된다. (default)
ignore_index = True : other가 가지고 있던 index가 무시되고, DataFrame의 index가 추가된다.
append() 메서드를 사용할 때는 동일한 column 이름을 설정해줘야 한다. 만약 column 이름이 다르면 새로운 column이 생기며 column과 row가 동시에 늘어난다. 값이 제공되지 않은 위치 값은 NaN으로 표시된다.
|
append_data = pd.Series([100, 200], ['국어','수학'])
result = data.append(append_data, ignore_index=False)
print(result)
|
결과
|
번호 국어 영어 수학 과학
0 1번 70.0 56.0 65.0 45.0
1 2번 65.0 95.0 98.0 95.0
2 3번 80.0 65.0 54.0 68.0
3 4번 68.0 95.0 68.0 78.0
4 5번 95.0 85.0 75.0 95.0
5 6번 62.0 75.0 95.0 45.0
6 7번 35.0 65.0 84.0 95.0
7 8번 78.0 68.0 92.0 65.0
8 9번 56.0 94.0 34.0 84.0
9 10번 50.0 51.0 68.0 95.0
10 11번 64.0 67.0 95.0 68.0
11 12번 89.0 84.0 78.0 79.0
12 13번 65.0 92.0 95.0 45.0
13 14번 59.0 65.0 64.0 92.0
14 15번 32.0 78.0 95.0 68.0
15 16번 21.0 65.0 46.0 94.0
16 NaN 100.0 NaN 200.0 NaN
|