customers= pd.read_csv('marketing_campaign.csv', sep='\t')
customers.head()
marketing_campaign.csv 을 customers라는 이름의 데이터프레임으로 생성customers.info()
# 집계통계 기술
customers.describe().round(1)
# 집계통계 기술 - 숫자 아닌 정보 확인
# 집계통계 기술
customers.describe(exclude=['int','float']).round(1)
# 나이 계산 - 데이터셋이 2021.08.23임
2021 - customers['Year_Birth']
customers['Year_Birth'] 빼기ID
5524 64
2174 67
4141 56
6182 37
5324 40
..
10870 54
4001 75
7270 40
8235 65
9405 67
Name: Year_Birth, Length: 2240, dtype: int64
# 연도 옆에 추가
customers.insert(1, 'Age', 2021 - customers['Year_Birth'])
customers.head()
def classify_age(age):
if age >= 0 and age <= 12:
return 'Child'
elif age >= 13 and age <= 19:
return 'Teenager'
elif age >= 20 and age <= 39:
return 'Young_Adult'
elif age >= 40 and age <= 64:
return 'Middle_aged'
elif age >= 65:
return 'Elderly'
else:
return 'Inavlid_age'
classify_age(9), classify_age(17), classify_age(20), classify_age(59), classify_age(65)
('Child', 'Teenager', 'Young_Adult', 'Middle_aged', 'Elderly')
customers['Age'].apply(classify_age)
ID
5524 Middle_aged
2174 Elderly
4141 Middle_aged
6182 Young_Adult
5324 Middle_aged
...
10870 Middle_aged
4001 Elderly
7270 Middle_aged
8235 Elderly
9405 Elderly
Name: Age, Length: 2240, dtype: object
people_set = {
'Name' : ['Spencer', 'Mark', 'Tom', 'Peter'],
'Major': ['Computer', 'Science', 'English', 'Computer'],
'YearOfJoining' : [2020, 2019, 2018, 2017],
'DriverLicense' : [True, False, False, True],
'TeacherCertification' : [True, False, False, False],
}
| Name | Major | YearOfJoining | DriverLicense | |
|---|---|---|---|---|
| 0 | Spencer | Computer | 2020 | True |
| 1 | Mark | Science | 2019 | False |
| 2 | Tom | English | 2018 | False |
| 3 | Peter | Computer | 2017 | True |
# map() 으로 매핑 확인해서 값 변환
people['DriverLicense'].map({True :'Yes', False: 'No'})
0 Yes
1 No
2 No
3 Yes
Name: DriverLicense, dtype: object
people.applymap(type)
people.applymap(str).applymap(type)
# str같은 경우 Series는 applymap할 필요 없이 가능하나
people['Name'].str.len()
# Dataframe은 .str이 안된다.
people.str()
# 대문자 만드는 함수
def uppercase(data):
return data.upper()
people.applymap(str).applymap(uppercase)
| dtype | 설명 |
|---|---|
| int64 | 정수형 데이터 |
| float64 | 실수형 데이터 |
| object | 문자열 데이터 |
| bool | 불리언(참/거짓) 데이터 |
| datetime64 | 날짜 및 시간 데이터 |
| timedelta | 두 날짜 또는 시간 간격 데이터 |
| category | 카테고리 형식의 데이터 |
| int8 | 8비트 정수형 데이터 |
| int16 | 16비트 정수형 데이터 |
| int32 | 32비트 정수형 데이터 |
| float16 | 16비트 실수형 데이터 |
| float32 | 32비트 실수형 데이터 |
| complex64 | 64비트 복소수형 데이터 |
| complex128 | 128비트 복소수형 데이터 |
# int64 -> int16 탄생연도
customers['Year_Birth'].astype('uint16')
customers["Marital_Status"].value_counts()
| 결혼 상태 | 인원 수 | 뜻 |
|---|---|---|
| Married | 864 | 기혼 |
| Together | 580 | 동거 |
| Single | 480 | 독신 |
| Divorced | 232 | 이혼 |
| Widow | 77 | 미망 |
| Alone | 3 | 혼자, 싱글 |
| Absurd | 2 | 터무니없는 |
| YOLO | 2 | 욜로 인생 |
이 중 Alone, Absurd, YOLO는 해석에 애매한 부분이 있다.
해당 데이터의 토론에도 이슈가 있으며
YOLO같은 경우는 일반적인 Single과는 다른 고객패턴이 있음을 표시하고 싶었던 것 일수도.
여기서는 이 3가지를 Single로 귀속시켜보자.
# 방법 1. 시리즈.replace(dict)
customers["Marital_Status"].replace({'Alone' : 'Single', 'Absurd' : 'Single' , 'YOLO' :'Single'})
# 방법 2. 시리즈.replace(to_replace:list, value)
customers["Marital_Status"].replace(['Alone', 'Absurd', 'YOLO'], 'Single')
# 방법 3. 데이터프레임.replace()
customers.replace({'Alone' : 'Single', 'Absurd' : 'Single' , 'YOLO' :'Single'})
# Inplcae=True로 원본에 반영하기
customers.replace({'Alone' : 'Single', 'Absurd' : 'Single' , 'YOLO' :'Single'}, inplace=True)
customers.where(customers['Kidhome'] >= 2)
# .where()이후 .dropna()
customers.where(customers['Kidhome'] >= 2).dropna()
다자녀가 아니면 데이터프레임에서 제거후 출력
조건에 맞지 않느 데이터 은닉 방법
# 방법 1. other로 대체하기
customers.where(customers['Kidhome'] >= 2, other='ooo')
# 방법 2. default인 NA가 되도록 놓거나 other에 None으로 대체하기
customers.where(customers['Kidhome'] >= 2, other='None')
.agg()
지정된 축(axis)을 기준으로 하나 이상의 연산을 사용하여 데이터를 집계(aggregate) 하는 기능을 제공
parameter
func : function, str, list or dictaxis : {0 or ‘index}args와 *kwargs: 함수에 전달할 위치 인자와 키워드 인자를 지정할 수 있다.return
scalar, Series or DataFrame
# 방법1. dict로 전달
# Income -> max, Kidhome -> mean
customers.agg({'Income' : 'max', 'Kidhome' : 'mean'})
Income 666666.000000
Kidhome 0.444196
dtype: float64
# 방법2. dict없이 str 또는 list로 전달하기
customers.agg('max')
# max, min
customers.agg(['max', 'min'])
# max, min, mean
customers.agg(['max', 'min', 'mean'])
['Education', 'Marital_Status', 'Dt_Customer'] 열에 숫자형이 아닌 데이터가 포함되어 있기 때문에 에러가 발생.# 대처 1 : drop() agg() 체인형으로 해결
customers.drop(columns=['Education', 'Marital_Status', 'Dt_Customer']).agg(['max', 'min', 'mean'])
# 대처 2 : 새로운 df를 만들어 해결
customers_nemeric = customers.select_dtypes(include='number')
customers_nemeric.agg(['max', 'min', 'mean'])
# 대처 3 : 원본에서 제거. 대처1을 파괴적으로 처리하는 방법
customers.drop(columns=['Education', 'Marital_Status', 'Dt_Customer'], inplace=True)
customers_nemeric.agg(['max', 'min', 'mean'])
customers.agg(['max', 'min', 'mean'], numeric_only=True)
# numeric_only=True는 agg() 메소드에는 적용되지 않는 옵션
# numeric_only=True 옵션은 max(), min(), mean() 등과 같은 집계 함수에 적용될 때 사용
# 복제 방법
customers_copy = customers.copy()
# 주소 비교
id(customers), id(customers_copy)
(2273371876880, 2273376423824)
멀티인덱스? 멀티인덱싱?
멀티 인덱스 설정 방법 1
customers = pd.read_csv('marketing_campaign.csv', sep='\t', index_col=['ID', 'Marital_Status'])
customers
| ID | Marital_Status |
|---|
customers.set_index(['ID', 'Marital_Status'], inplace=True)
MultiIndex([( 5524, 'Single'),
( 2174, 'Single'),
( 4141, 'Together'),
( 6182, 'Together'),
( 5324, 'Married'),
( 7446, 'Together'),
( 965, 'Divorced'),
( 6177, 'Married'),
( 4855, 'Together'),
( 5899, 'Together'),
...
( 7004, 'Single'),
( 9817, 'Single'),
( 8080, 'Single'),
( 9432, 'Together'),
( 8372, 'Married'),
(10870, 'Married'),
( 4001, 'Together'),
( 7270, 'Divorced'),
( 8235, 'Together'),
( 9405, 'Married')],
names=['ID', 'Marital_Status'], length=2240)
customers.index.get_level_values(0)
인덱스 레벨이 0인 것만 출력
.swaplevel()
customers.swaplevel()