오랜만에 사용하려고 하면 늘 헛갈리는 파이썬 데이터프레임 다루기.
사실 헛갈리는 이유는 동일한 결과를 낼 수 있는 방법이 너무 많기 때문이라고 생각한다.
개인적으로 가장 심플하다고 생각하는 방법 하나씩만 정리해 둔다.
1. 특정 열 인덱싱
df_temp = df.loc[:, ['a']]
df['a'] 같은 방식은 잊어버리자. 나중에 행 인덱싱할 때 꼭 df[0,] 같은 것도 동작할 것처럼 착각하게 된다.
그냥 인덱싱은 무조건 loc 사용한다고 생각하는 편이 맘 편하다.
[:] 은 all 의 의미.
열 이름을 굳이 리스트에 담아 전달하는 것은 익숙해질 때까지 다소 어색하지만 두 가지 이점이 있다.
1. 하나의 열만 인덱싱하더라도 결과가 데이터프레임으로 반환된다. (df.loc[:, 'a'] 의 결과는 판다스 시리즈로 반환된다.)
2. 콤마를 사용하면 여러 개의 열을 동시에 인덱싱할 수도 있다.
2. 특정 행 인덱싱
df_temp = df.loc[[0], :]
df['a'] 같은 방식은 잊어버리자(2)
그럼 그냥 열 인덱싱의 반대일 뿐이다.
행 이름을 굳이 리스트에 담아 전달하는 것은(...이하 생략)
3. 순서로 열이나 행 인덱싱
df_temp = df.iloc[:, [0]]
location 대신 integer location 을 사용한다는 것만 다르다
4. ~부터 ~까지 인덱싱
df_temp = df.iloc[0:4, :]
역시 integer location 을 사용하면 된다. 위는 첫 행부터 4개의 행을 인덱싱, 아래는 두 번째 열부터 5개의 열을 인덱싱
df_temp = df.iloc[:, 1:6]
범위 인덱싱은 범위 자체가 리스트이므로 당연히 결과가 판다스 데이터프레임으로 반환된다.
'마지막에서 몇 개 행'을 인덱싱하는 것은 위 예에 비해서는 직관적이지 않다. 아래는 마지막에서부터 60개 열을 인덱싱하는 예다.
df_temp = df.iloc[-60:, :]
5. 정렬
df_temp = df.sort_values('a', ascending=True)
혹시 특정 열이 아니라 index를 활용해 정렬하려면 다음과 같이
df_temp = df.sort_index(ascending=False)
정렬 후에는 인덱스 초기화가 필요하다.
df_temp = df_temp.reset_index(drop=True)
6. 데이터프레임끼리 합치기
df_temp = pandas.concat([df1, df2], axis='rows')
df1, df2를 리스트로 전달해야 한다는 게 함정
위 예는 행 방향(아래)으로 합친다. 열 방향(옆)으로 합치려면 axis='columns' 만 바꾸면 된다.
행 방향으로 합친 후엔 역시 인덱스 초기화가 필요하다. (ignore_index=True 같은 옵션도 있으나 헛갈리므로 알아두지 말기로 하자)
7. 마지막 행에 개별 데이터 추가하기
df.loc[len(df), 'a'] = value
이게 제일 기억하기 쉽다. 근데 값을 추가하는 순간 len(df) 값이 달라지므로, 반복문 내에서 마지막 행 여러 열에 값을 추가해야 할 때는 반복문 처음에 last_row = len(df) 와 같이 값을 하나 고정해 놓고 last_row 행에 추가하는 방식이 좋다.
8. A열의 값이 1인 바로 그 행의 B열 값
df.loc[df.loc[:, 'a'] == 1, 'b']
'행' 부분에 df.loc[:, 'a'] == 1 을 적어주었을 뿐이다.
단일 데이터 인덱싱이므로 인수로 리스트를 사용하지 않는 df.loc[0, 'a'] 를 기본형으로 생각하자.
9. 특정 열 삭제
df = df.drop(['a', 'b'], axis='columns')
역시 삭제하고 싶은 열을 리스트로 전달해야 한다는 게 함정.
df = 을 사용하지 않는 df.drop(... inplace=True) 같은 것도 있으나 역시 모르기로 하자.
행은 columns 를 rows 로만 바꿔주면 된다.
10. 데이터프레임 마지막 행 구글시트에 추가하기
scope / json_file_name / credentials / gc 등의 선언이 완료되었다는 가정 하에
url = 'https://...'
doc = gc.open_by_url(url)
sheet = doc.worksheet('sheet_name')
sheet.append_row(df.iloc[-1, :].values.tolist(), table_range='A1')
iloc의 -1은 순서상 마지막을 의미
table_range 는 append하는 기준, 생략하면 이미 데이터가 있을 경우 빈 열에 붙인다거나 하는 오동작이 있다.
근데 가끔 df.iloc[-1, :].values.tolist() 부분에서 Object of type 'int64' is not JSON serializable 같은 에러가 날 때가 있다. 데이터프레임에서 쓰던 자료형이 호환이 안 된다는 얘기인데... 처리하는 세련된 방법이 당연히 있겠지만 따로 기억하기 귀찮으니 다음과 같이 다소 무식하게(?) 리스트를 생성해서 append_row()에 넣는 것도 방법이겠다.
temp_df = df.iloc[-1, :]
temp_list = []
for i in range(len(temp_df)):
temp_list.append(float(temp_df[i]))
참고로 데이터 업데이트 전 구글시트 clear가 필요하다면 다음 코드를 사용. 이런 건 어쩔 수 없이 기억(록)해 둬야 한다.
sheet.batch_clear(['A1:B2'])
'컴퓨터' 카테고리의 다른 글
한글(hwp)문서 여러개 한꺼번에 하나로 합치기 (19) | 2020.02.13 |
---|---|
[윈도우] 화면 캡쳐하여 파일로 저장하기 단축키 (0) | 2019.05.13 |
IFTTT에서 인스타그램 연결이 되지 않을 때(could not connect service) (0) | 2019.04.12 |
유튜브 반응형 영상 링크 삽입(embed) 소스 (3) | 2018.12.26 |
Bitly 시간대는 변경이 가능할까? GMT, UTC, KST가 헛갈리는 이유는? (0) | 2018.12.24 |
[컴퓨터] 그림판으로 화면 내 특정 색의 RGB값 알아보기 (0) | 2018.10.23 |
[크롬] 특정 사용자계정의 바로가기 만들기 (1) | 2018.10.11 |
구글 프레젠테이션에서 이미지 작업하기 (문서 크기 변경, 저장) (1) | 2018.10.08 |
외장하드 만들고 초기설정하기 (feat. MG877K) (3) | 2018.08.29 |
[파워포인트] 포토샵 대신 파워포인트 쓰기(문서 크기 조절, 그림으로 저장) (1) | 2018.06.15 |
댓글