본문 바로가기
Study/혼자 공부하는 판다스

혼자 공부하는 판다스 - 데이터프레임의 다양한 응용(함수 매핑, 열 재구성)

by Wanooky 2022. 4. 26.

개별 원소에 함수 매핑

 

시리즈 객체에 apply() 메소드를 적용하면 인자로 전달하는 함수에 시리즈의 모든 원소를 하나씩 입력하고 함수의 리턴값을 돌려 받는다.

 

이는 다음과 같이 작성한다.

 

Series.apply(매핑 함수)

 

import seaborn as sns

titanic = sns.load_dataset('titanic')
df = titanic.loc[:, ['age', 'fare']]
df['ten'] = 10

def add_10(n):
	return n + 10
    
def add_two_obj(a, b):
	return a + b

print(add_10(10))
print(add_two_obj(10, 10))

20
20

 

먼저 다음과 같이 두 함수를 정의했다. 그 다음에 apply 메소드를 적용하여 변수 sr1에 저장한다.

 

sr2에는 add_two_obj를 apply 메소드에 적용하는데, 이때 변수가 2개이므로 a에는 add_two_obj의 리턴값,

b에는 10을 정의해준다.

 

sr3에는 lambda 함수를 활용하여 시리즈 객체에 적용한다.

 

 

sr1 = df['age'].apply(add_10)
print(sr1.head())

sr2 = df['age'].apply(add_two_obj, b=10)
print(sr2.head())

sr3 = df['age'].apply(lambda x: add_10(x))
print(sr3.head())

0    32.0
1    48.0
2    36.0
3    45.0
4    45.0
Name: age, dtype: float64


0    32.0
1    48.0
2    36.0
3    45.0
4    45.0
Name: age, dtype: float64


0    32.0
1    48.0
2    36.0
3    45.0
4    45.0
Name: age, dtype: float64

이번엔 데이터프레임 원소에 함수를 매핑해보자

 

DataFrame.applymap(매핑함수)

 

df_map = df.applymap(add_10)
print(df_map.head())

    age     fare  ten
0  32.0  17.2500   20
1  48.0  81.2833   20
2  36.0  17.9250   20
3  45.0  63.1000   20
4  45.0  18.0500   20

 

데이터프레임의 각 열에 함수를 매핑하는 방법은 axis=0으로 지정한다

 

DataFrame.apply(매핑 함수, axis=0)

 

missing_value() 함수를 정의하여 사용해보자.

 

titanic = sns.load_dataset('titanic')
df = titanic.loc[:, ['age', 'fare']]

def missing_value(series):
  return series.isnull()
  
result = df.apply(missing_value, axis=0)
print(result.head())
print(type(result))

     age   fare
0  False  False
1  False  False
2  False  False
3  False  False
4  False  False

 

적용되는 과정은 다음과 같다.

 

데이터프레임의 각 열을 매핑 함수에 전달하면, 각 열의 리턴값은 하나의 값으로 반환되고 마지막으로 이들 값을 하나의 시리즈로 통합하는 과정을 거치게 된다.

 

이 때 각 열의 이름이 시리즈의 인덱스가 되고, 함수가 반환하는 값이 각 인덱스에 매칭되는 데이터 값이 된다.

 

axis=0 옵션은 따로 설정하지 않아도 apply() 함수에서 기본 적용된다.

 

def min_max(x):
	return x.max() - x.min()
    
result = df.apply(min_max)
print(result)
print('\n')
print(type(result))

age      79.5800
fare    512.3292
dtype: float64


<class 'pandas.core.series.Series'>

데이터프레임의 각 행에 함수를 매핑하는 방법은 axis=1로 적용한다.

 

titanic = sns.load_dataset('titanic')
df = titanic.loc[:, ['age', 'fare']]
df['ten'] = 10

def add_two_obj(a, b):
  return a+b
  
df['add'] = df.apply(lambda x: add_two_obj(x['age'], x['ten']), axis=1)
print(df.head())

    age     fare  ten   add
0  22.0   7.2500   10  32.0
1  38.0  71.2833   10  48.0
2  26.0   7.9250   10  36.0
3  35.0  53.1000   10  45.0
4  35.0   8.0500   10  45.0

 

데이터프레임 객체 자체를 함수에 매핑하려면 pipe() 메소드를 사용한다.

 

DataFrame.pipe()

 

titanic = sns.load_dataset('titanic')
df = titanic.loc[:, ['age', 'fare']]

def missing_value(x):
	return x.isnull()
    
def missing_count(x):
	return missing_value(x).sum()

def total_number_missing(x):
	return missing_count(x).sum()
    
result_df = df.pipe(missing_value)
print(result_df.head())
print(type(result_df))

     age   fare
0  False  False
1  False  False
2  False  False
3  False  False
4  False  False
<class 'pandas.core.frame.DataFrame'>

 

result_series = df.pipe(missing_count)
print(result_series)
print(type(result_series))

age     177
fare      0
dtype: int64
<class 'pandas.core.series.Series'>

 

result_value = df.pipe(total_number_missing)
print(result_value)
print(type(result_value))

177

열 순서 변경

 

열 순서를 변경하는 방법은 다음과 같다

 

DataFrame[재구성한 열 이름의 리스트]

 

import seaborn as sns

titanic = sns.load_dataset('titanic')
df = titanic.loc[0:4, 'survived':'age']
print(df, '\n')

   survived  pclass     sex   age
0         0       3    male  22.0
1         1       1  female  38.0
2         1       3  female  26.0
3         1       1  female  35.0
4         0       3    male  35.0

열 이름 배열을 나타내는 df.columns.values 속성을 선택하여 파이썬 list() 함수에 전달해보자

 

columns = list(df.columns.values)
print(columns, '\n')

['survived', 'pclass', 'sex', 'age']

 

sorted() 함수에 columns 변수를 입력하면 열 이름이 알파벳 순으로 정렬이 되는데,

 

이를 이용하여 데이터프레임의 열 순서를 변경해보자.

 

columns_sorted = sorted(columns)
df_sorted = df[columns_sorted]
print(df_sorted, '\n')

    age  pclass     sex  survived
0  22.0       3    male         0
1  38.0       1  female         1
2  26.0       3  female         1
3  35.0       1  female         1
4  35.0       3    male         0

 

기존 순서의 정반대 역순으로 정렬할 수 있는데, reversed() 함수에 columns 변수를 전달하면 된다.

 

columns_reversed = list(reversed(columns))
df_reversed = df[columns_reversed]
print(df_reversed, '\n')

    age     sex  pclass  survived
0  22.0    male       3         0
1  38.0  female       1         1
2  26.0  female       3         1
3  35.0  female       1         1
4  35.0    male       3         0

열 이름을 사용자가 정의한 순서대로 재배치 할 수 있다.

 

columns_customed = ['pclass', 'sex', 'age', 'survived']
df_customed = df[columns_customed]
print(df_customed)

   pclass     sex   age  survived
0       3    male  22.0         0
1       1  female  38.0         1
2       3  female  26.0         1
3       1  female  35.0         1
4       3    male  35.0         0

하나의 열이 여러가지 정보를 담고 있을때, 각 정보를 서로 분리해서 사용할 수 있다.

 

이때, 열 분리를 한다.

 

import pandas as pd

df = pd.read_excel('/content/drive/MyDrive/part6/주가데이터.xlsx')
print(df.head(), '\n')
print(df.dtypes, '\n')


         연월일   당일종가  전일종가     시가     고가     저가     거래량
0 2018-07-02  10100   600  10850  10900  10000  137977
1 2018-06-29  10700   300  10550  10900   9990  170253
2 2018-06-28  10400   500  10900  10950  10150  155769
3 2018-06-27  10900   100  10800  11050  10500  133548
4 2018-06-26  10800   350  10900  11000  10700   63039 

연월일     datetime64[ns]
당일종가             int64
전일종가             int64
시가               int64
고가               int64
저가               int64
거래량              int64
dtype: object

 

연월일을 연, 월, 일로 분리해보자.

 

df['연월일'] = df['연월일'].astype('str')
dates = df['연월일'].str.split('-')
print(dates.head(), '\n')

0    [2018, 07, 02]
1    [2018, 06, 29]
2    [2018, 06, 28]
3    [2018, 06, 27]
4    [2018, 06, 26]
Name: 연월일, dtype: object

 

시리즈를 문자열 리스트의 원소를 선택하는, 즉 인덱싱 하기 위해서 get() 메소드를 사용한다.

 

df['연'] = dates.str.get(0)
df['월'] = dates.str.get(1)
df['일'] = dates.str.get(2)
print(df.head())

          연월일   당일종가  전일종가     시가     고가     저가     거래량     연   월   일
0  2018-07-02  10100   600  10850  10900  10000  137977  2018  07  02
1  2018-06-29  10700   300  10550  10900   9990  170253  2018  06  29
2  2018-06-28  10400   500  10900  10950  10150  155769  2018  06  28
3  2018-06-27  10900   100  10800  11050  10500  133548  2018  06  27
4  2018-06-26  10800   350  10900  11000  10700   63039  2018  06  26
[ ]