Computer Science/Python

[Pandas] 판다스 기초 자료형 (DataFrame, Series) 및 관련 코드

2021. 3. 15. 18:12

Pandas 기본 개념

Pandas에서 Series는 하나의 column이나 row, DataFrame은 여러 series의 collection(엑셀 sheet, 파이썬 dictionary)이라고 생각하면 된다. 그리고 DataFrame에서 axis=0은 열 방향, axis=1은 행 방향이다. 또 각각의 row는 index를 가지고 있는데, index의 이름은 column 이름과 구분된다 (index 이름이 없는 경우도 있다).

DataFrame

 

Series 및 DataFrame을 다루는 관련 python 코드는 다음과 같다.

 

Series 생성 및 확인

import pandas as pd # pandas package importing

# Series 생성
s = pd.Series(['a','b'], index=['first','second']) # index는 optional


# Series 확인
print(s.index) # index 확인
# Index(['first', 'second'], dtype='object')

print(s.keys) # Key 확인
# <bound method Series.keys of first     a
# second    b
# dtype: object>

print(s.values) # values 확인
# ['a' 'b']

s.value_counts() # value counts 확인
0    1122
1     291
Name: column1, dtype: int64

 

DataFrame 생성 및 확인

# DataFrame 생성
df = pd.DataFrame({
	'Column1': ['a','b'],
    'Column2': ['value1','value2']}
)
df = pd.DataFrame( # 인덱스 지정
	data={'Column1': ['a','b'],
    	  'Column2': ['value1','value2']},
    index=['first','second'],
    columns=['Column2','Column1'] # Column 순서 지정 가능
)
df = pd.DataFrame(OrderedDict([ # 순서 지정
	('Column1', ['a','b']),
    ('Column2', ['value1','value2'])
    ])
)

# DataFrame 확인
print(df.head()) # Head 확인
print(df.head(n=5))

print(df.tail(n)) # Tail 확인

print(type(df)) # type 확인: DataFrame
# <class 'pandas.core.frame.DataFrame'>

print(df.shape) # 행과 열의 크기 확인
# (2, 2)

print(df.columns) # Column 이름 확인
# Index(['Column1', 'Column2'], dtype='object')

print(df.dtypes) # 각 column의 data type 확인
# Column1    object
# Column2    object
# dtype: object

print(df.info()) # 구체적인 정보 확인 가능

 

DataFrame 조작

del df['Column1'] # Column1 삭제
df.drop(['Column1'], axis=1) # Column1 삭제

df = df.drop_duplicates() # 중복 삭제

df['columnStr'] = df['column'].astype(str) # Series의 자료형 변환 (String으로)
df['columnCategory'] = df['column'].astype('category') # Series의 자료형 변환 (Category로, 용량 및 속도에서 효율적)
df['columnNumeric'] = df.to_numeric(df['column'], errors='coerce') # Series의 자료형 변환 (Numeric으로), 숫자로 변환할 수 없을 때는 NaN으로

df.sort_values(by=['col1'], ascending=False, na_position='first') # 정렬 (sorting), ascending, na_position은 생략 가능

# Column name 변경 방법 1
df.columns = ['NewColumn1', 'NewColumn2']

# Column name 변경 방법 2
df = df.rename({'Column1': 'NewColumn1', 'Column2': 'NewColumn2'}, axis=1)

# Column value split
df['column'] = df['column'].str.split('-').str[0] # ex) 'Tom-1'이 'Tom'으로 저장

# Sorting
df.sort_values('column')
df.sort_values('column', ascending=False)

 

Iterate (for loop)

# For DataFrame
for index, row in df.iterrows():
    print(row['c1'], row['c2'])
    
# For Series
for index, item in series.iteritems(): # or series.items()
    print(index, item)

 

Data importing & exporting

# Data importing & exporting
df.to_pickle('[FILE PATH]') # pickle로 저장 (binary, 용량이 작다)
df.read_pickle('[FILE PATH]') # pickle importing

df.to_csv('[FILE PATH]', sep='\t') # CSV(TSV)로 저장
df = pd.read_csv('[FILE PATH]', sep='\t') # CSV(TSV) importing

# 여러 개의 데이터
import glob
dataArray = glob.glob('./*.csv')
print(dataArray)
# ['./file1.csv',
# './file2.csv']

df1=pd.read_csv(dataArray[0])
df2=pd.read_csv(dataArray[1])

 

데이터 추출

# 데이터 추출
df['column1'] # 열 단위 데이터 추출
df[['column1','column2']]

df.loc[0] # 행 단위 데이터 추출 (인덱스 이용)
df.loc[[0,1,2]]

df.iloc[-1] # 행 단위 데이터 추출 (순서 이용)
df.iloc[[0,1,2]]

df.loc[:, ['column1','column2']] # 행과 열 단위 데이터 추출
df.iloc[:, [0,1]] # 행과 열 단위 데이터 추출

df['column1'] > df['column1'].mean() # Boolean 추출
df.loc[df.column1>100, :] # Boolean 추출

df.sample(10) # 일부 추출

 

Group 맺기

# 값 확인
print(df.groupby('column1')['column2'].mean()) # column1으로 그룹을 만들고, 각 그룹의 column2 평균을 표시
print(df.groupby('column1').column2.mean())
print(df.groupby('column1').mean()) # column1을 제외한 전체 columns의 평균 반환
print(df.groupby(['column1','column2']).mean()) # column1, 2를 제외한 전체 columns의 평균 반환

print(df.groupby('column1')['column2'].nunique()) # column1으로 그룹을 만들고, 각 그룹의 unique한 column2 수를 표시
print(df.groupby('column1').column2.nunique())

print(df.groupby('column1').column2.agg([myFunc, mean, nunique])) # myFunc, mean, nuique의 return 값을 한번에 반환


# 값 변환
def fillNaAvg(x):
	avg = x.mean()
    return x.fillna(avg)
print(df.groupby('column1').column2.transform(fillNaAvg)) # column1으로 그룹을 만들고, 각 그룹의 column2 값 평균으로 NaN을 채워준다.


# 데이터 필터링
print(df.groupby('column1').filter(lambda x: x['column1'].count()>=10)) # column1으로 그룹을 만들고, 각 그룹의 elements 수가 10개 이상인 경우만 표시

집계 함수에는 count(NaN 제외 데이터 수), size(NaN 포함 데이터 수), mean, min, max, quantile(q=0.5), sum, var 등이 있다.

 

그래프 생성

# 그래프 생성
%matplotlib inline # Jupyter에서 그래프를 그리기 위한 magic function
df.groupby('column1')['column2'].mean().plot()

# 크기 조절
df.plot(figsize=(12,8))

 

데이터 결합

# 1. concat (index가 같은 경우)
rowConcat = pd.concat([df1, df2]) # DataFrame 연결 (Row), Series도 가능
columnConcat = pd.concat([df1, df2], axis=1) # 같은 index끼리 DataFrame 연결 (Column), Series도 가능
'''
ignore_index=True: 인덱스를 0부터 새로 생성
join='inner': 공통 행/열만 묶어줌 (같은 index)
'''

# 2. concat (index가 다른 경우)
# index가 다른 개체를 columnConcat하고 싶을 때는 set_index로 index를 바꿔준 후 합쳐줄 수 있다.
pd.concat([df.set_index(['column1', 'column2']) for df in [df1, df2]], axis=1) # 다음과 같이 MultiIndex도 가능

# 3. append
rowConcat = df1.append(df2) # DataFrame 연결

# 4. []
df1['new']=[1, 2, 3] # 열 추가
df1.loc['new']=[1, 2, 3] # 행 추가

# 5. merge
dfMerge = df1.merge(df2, on=['df1_column'])
dfMerge = df1.merge(df2, left_on='df1_column', right_on='df2_column')

 

NaN 처리

# NaN 수
print(df.shape[0]-df.count())

# NaN 변경
df.fillna(0) # 0으로 변경

# NaN 삭제
df.dropna()

# NaN 포함 계산
df.column.sum(skipna = False) # NaN은 0으로 계산, skipna = True이면 NaN return.

 

데이터 피벗 (melt, pivot_table)

df = pd.DataFrame({
	'Student': ['Tom','Jane','Harry'],
    'Semester1': [100,90,80],
    'Semester2': [50,80,70]}
)
meltDf = pd.melt(df, id_vars=['Student'], value_vars=['Semester1','Semester2'], var_name='Semester', value_name='Score') # value_vars=['Semester1','Semester2'] 생략 가능
print(meltDf)
  Student   Semester  Score
# 0     Tom  Semester1    100
# 1    Jane  Semester1     90
# 2   Harry  Semester1     80
# 3     Tom  Semester2     50
# 4    Jane  Semester2     80
# 5   Harry  Semester2     70

pivotDf = meltDf.pivot_table(index=['Student'],columns='Semester',values='Score')
print(pivotDf)
# Semester  Semester1  Semester2
# Student                       
# Harry            80         70
# Jane             90         80
# Tom             100         50

pivotDf = meltDf.reset_index() # multiindex의 경우에 index를 새로 부여
print(pivotDf)
#    index Student   Semester  Score
# 0      0     Tom  Semester1    100
# 1      1    Jane  Semester1     90
# 2      2   Harry  Semester1     80
# 3      3     Tom  Semester2     50
# 4      4    Jane  Semester2     80
# 5      5   Harry  Semester2     70

 

Broadcasting (apply)

def calculate(values, n):
    sum=0
    for value in values:
        sum+=value
    return sum/len(values)*n

# DataFrame 생성
df = pd.DataFrame({'column1':[1,2,3],'column2':[4,5,6]})
print(df)
#    column1  column3
# 0        1        4
# 1        2        5
# 2        3        6

print(df.apply(calculate, axis=0, n=100)) # axis=0 열 방향
# column1    200.0
# column2    500.0
# dtype: float64

print(df.apply(calculate, axis=1, n=100)) # axis=1 행 방향
# 0    250.0
# 1    350.0
# 2    450.0
# dtype: float64

 

Datetime 자료형

dateSeries = pd.Series(['2021-04-14','2021-04-15'])
dateSeries = pd.to_datetime(dateSeries) # 자료형을 datetime으로 바꿔줌.

print(dateSeries)
# 0   2021-04-14
# 1   2021-04-15
# dtype: datetime64[ns]

print(dateSeries[0].year)
# 2021

print(dateSeries[0].month)
# 4

print(dateSeries[0].day)
# 14

print(dateSeries.dt.year)
# 0    2021
# 1    2021
# dtype: int64

 

유용한 작업 모음

1. 특정 값을 가진 row를 검색 [4]

# 특정 값을 갖는 row 선택
df.loc[df['column_name'] == 'value']
df.loc[df['column_name'].isin(['value1', 'value2'])]
df.loc[(df['column_name'] >= 5) & (df['column_name'] <= 10)]

# 특정 값을 갖지 않는 row 선택
df.loc[df['column_name'] != some_value]
df.loc[~df['column_name'].isin(some_values)]

# 특정 index를 갖는 row 선택
df.loc['index1']
df.loc[df.index.isin(['index1','index2'])]

 

 

Reference

  1. Do it! 데이터 분석을 위한 판다스 입문
  2. fenderist.tistory.com/83
  3. stackoverflow.com/questions/16476924/how-to-iterate-over-rows-in-a-dataframe-in-pandas
  4. https://stackoverflow.com/questions/17071871/how-do-i-select-rows-from-a-dataframe-based-on-column-values

 

 

 

728x90
반응형