반응형
DataFrame 연결¶
In [1]:
import numpy as np
import pandas as pd
df1 = pd.DataFrame({'a':['a0', 'a1', 'a2', 'a3'],
'b':[1,2,3,4],
'c':['c0','c1','c2','c3']},
index=[0,1,2,3])
df1
Out[1]:
a | b | c | |
---|---|---|---|
0 | a0 | 1 | c0 |
1 | a1 | 2 | c1 |
2 | a2 | 3 | c2 |
3 | a3 | 4 | c3 |
In [2]:
df2 = pd.DataFrame({'b':[5,6,7,8],
'c':['c0','c1','c2','c3'],
'd':['d0','d1','d2','d3'],
'e':['e0','e1','e2','e3']},
index=[2,3,4,5])
df2
Out[2]:
b | c | d | e | |
---|---|---|---|---|
2 | 5 | c0 | d0 | e0 |
3 | 6 | c1 | d1 | e1 |
4 | 7 | c2 | d2 | e2 |
5 | 8 | c3 | d3 | e3 |
In [3]:
result_df = pd.concat([df1,df2], axis=0)
result_df
Out[3]:
a | b | c | d | e | |
---|---|---|---|---|---|
0 | a0 | 1 | c0 | NaN | NaN |
1 | a1 | 2 | c1 | NaN | NaN |
2 | a2 | 3 | c2 | NaN | NaN |
3 | a3 | 4 | c3 | NaN | NaN |
2 | NaN | 5 | c0 | d0 | e0 |
3 | NaN | 6 | c1 | d1 | e1 |
4 | NaN | 7 | c2 | d2 | e2 |
5 | NaN | 8 | c3 | d3 | e3 |
행방향 결합, axis = 0 : 2차원¶
In [4]:
result_df = pd.concat([df1, df2], axis=1)
result_df
Out[4]:
a | b | c | b | c | d | e | |
---|---|---|---|---|---|---|---|
0 | a0 | 1.0 | c0 | NaN | NaN | NaN | NaN |
1 | a1 | 2.0 | c1 | NaN | NaN | NaN | NaN |
2 | a2 | 3.0 | c2 | 5.0 | c0 | d0 | e0 |
3 | a3 | 4.0 | c3 | 6.0 | c1 | d1 | e1 |
4 | NaN | NaN | NaN | 7.0 | c2 | d2 | e2 |
5 | NaN | NaN | NaN | 8.0 | c3 | d3 | e3 |
열방향 결합, axis = 1 : 2차원¶
In [6]:
data1 = {'학번':[1,2,3,4],
'이름':['홍길동','김연아', '아이유','신사임당'],
'학년':[3,2,1,4]}
df1 = pd.DataFrame(data1)
df1
Out[6]:
학번 | 이름 | 학년 | |
---|---|---|---|
0 | 1 | 홍길동 | 3 |
1 | 2 | 김연아 | 2 |
2 | 3 | 아이유 | 1 |
3 | 4 | 신사임당 | 4 |
In [9]:
data2 = {'학번':[1,2, 4, 5],
'학과':['철학과','수학과', '컴퓨터', '국어국문'],
'학점':[1.2, 3.3, 2.7, 4.0]}
df2 = pd.DataFrame(data2)
In [10]:
result_df = pd.merge(df1, df2, on='학번', how='inner') # inner join. 학번이 일치하는 애들만 가져옴
result_df
Out[10]:
학번 | 이름 | 학년 | 학과 | 학점 | |
---|---|---|---|---|---|
0 | 1 | 홍길동 | 3 | 철학과 | 1.2 |
1 | 2 | 김연아 | 2 | 수학과 | 3.3 |
2 | 4 | 신사임당 | 4 | 컴퓨터 | 2.7 |
In [11]:
result_df = pd.merge(df1, df2, on='학번', how='outer') # outer join
result_df
Out[11]:
학번 | 이름 | 학년 | 학과 | 학점 | |
---|---|---|---|---|---|
0 | 1 | 홍길동 | 3.0 | 철학과 | 1.2 |
1 | 2 | 김연아 | 2.0 | 수학과 | 3.3 |
2 | 3 | 아이유 | 1.0 | NaN | NaN |
3 | 4 | 신사임당 | 4.0 | 컴퓨터 | 2.7 |
4 | 5 | NaN | NaN | 국어국문 | 4.0 |
In [12]:
result_df = pd.merge(df1, df2, on='학번', how='left') # left outer join, 일치하지 않는 것들 중 왼쪽의 것만 추가
result_df
Out[12]:
학번 | 이름 | 학년 | 학과 | 학점 | |
---|---|---|---|---|---|
0 | 1 | 홍길동 | 3 | 철학과 | 1.2 |
1 | 2 | 김연아 | 2 | 수학과 | 3.3 |
2 | 3 | 아이유 | 1 | NaN | NaN |
3 | 4 | 신사임당 | 4 | 컴퓨터 | 2.7 |
In [13]:
result_df = pd.merge(df1, df2, on='학번', how='right') # right outer join, 일치하지 않는 것들 중 오른쪽의 것만 추가
result_df
Out[13]:
학번 | 이름 | 학년 | 학과 | 학점 | |
---|---|---|---|---|---|
0 | 1 | 홍길동 | 3.0 | 철학과 | 1.2 |
1 | 2 | 김연아 | 2.0 | 수학과 | 3.3 |
2 | 4 | 신사임당 | 4.0 | 컴퓨터 | 2.7 |
3 | 5 | NaN | NaN | 국어국문 | 4.0 |
결합하려는 두 데이터의 컬럼명이 다를때!
In [14]:
data1 = {'학번':[1,2,3,4],
'이름':['홍길동','김연아', '아이유','신사임당'],
'학년':[3,2,1,4]}
df1 = pd.DataFrame(data1)
data2 = {'학생학번':[1,2, 4, 5],
'학과':['철학과','수학과', '컴퓨터', '국어국문'],
'학점':[1.2, 3.3, 2.7, 4.0]}
df2 = pd.DataFrame(data2)
In [16]:
result_df = pd.merge(df1, df2, left_on='학번', right_on='학생학번', how='inner')
result_df
Out[16]:
학번 | 이름 | 학년 | 학생학번 | 학과 | 학점 | |
---|---|---|---|---|---|---|
0 | 1 | 홍길동 | 3 | 1 | 철학과 | 1.2 |
1 | 2 | 김연아 | 2 | 2 | 수학과 | 3.3 |
2 | 4 | 신사임당 | 4 | 4 | 컴퓨터 | 2.7 |
인덱스를 이용해서 두 데이터를 결합할 때
In [19]:
data1 = {'학번':[1,2,3,4],
'이름':['홍길동','김연아', '아이유','신사임당'],
'학년':[3,2,1,4]}
df1 = pd.DataFrame(data1)
data2 = {'학과':['철학과','수학과', '컴퓨터', '국어국문'],
'학점':[1.2, 3.3, 2.7, 4.0]}
df2 = pd.DataFrame(data2, index=[1,2,4,5])
In [20]:
result_df = pd.merge(df1, df2,
left_on = '학번',
right_index= True,
how='inner')
result_df
Out[20]:
학번 | 이름 | 학년 | 학과 | 학점 | |
---|---|---|---|---|---|
0 | 1 | 홍길동 | 3 | 철학과 | 1.2 |
1 | 2 | 김연아 | 2 | 수학과 | 3.3 |
3 | 4 | 신사임당 | 4 | 컴퓨터 | 2.7 |
In [21]:
data1 = {'이름':['홍길동','김연아', '아이유','신사임당'],
'학년':[3,2,1,4]}
df1 = pd.DataFrame(data1, index=[1,2,3,4])
data2 = {'학과':['철학과','수학과', '컴퓨터', '국어국문'],
'학점':[1.2, 3.3, 2.7, 4.0]}
df2 = pd.DataFrame(data2, index=[1,2,4,5])
In [22]:
result_df = pd.merge(df1, df2,
left_index= True,
right_index= True,
how='inner')
result_df
Out[22]:
이름 | 학년 | 학과 | 학점 | |
---|---|---|---|---|
1 | 홍길동 | 3 | 철학과 | 1.2 |
2 | 김연아 | 2 | 수학과 | 3.3 |
4 | 신사임당 | 4 | 컴퓨터 | 2.7 |
In [24]:
import numpy as np
import pandas as pd
import seaborn as sns
In [25]:
df = sns.load_dataset('titanic')
df.head()
Out[25]:
survived | pclass | sex | age | sibsp | parch | fare | embarked | class | who | adult_male | deck | embark_town | alive | alone | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 3 | male | 22.0 | 1 | 0 | 7.2500 | S | Third | man | True | NaN | Southampton | no | False |
1 | 1 | 1 | female | 38.0 | 1 | 0 | 71.2833 | C | First | woman | False | C | Cherbourg | yes | False |
2 | 1 | 3 | female | 26.0 | 0 | 0 | 7.9250 | S | Third | woman | False | NaN | Southampton | yes | True |
3 | 1 | 1 | female | 35.0 | 1 | 0 | 53.1000 | S | First | woman | False | C | Southampton | yes | False |
4 | 0 | 3 | male | 35.0 | 0 | 0 | 8.0500 | S | Third | man | True | NaN | Southampton | no | True |
In [124]:
df = df.loc[:, ['age', 'fare']]
df.head()
Out[124]:
age | fare | |
---|---|---|
0 | 22.0 | 7.2500 |
1 | 38.0 | 71.2833 |
2 | 26.0 | 7.9250 |
3 | 35.0 | 53.1000 |
4 | 35.0 | 8.0500 |
함수 적용 apply()¶
axis를 명시해야함.
In [126]:
# min max scaling
def min_max(s) :
return (s - s.min()) / (s.max() - s.min())
result_df = df.apply(min_max, axis=0) # axis=0 열단위
result_df.head()
Out[126]:
age | fare | |
---|---|---|
0 | 0.271174 | 0.014151 |
1 | 0.472229 | 0.139136 |
2 | 0.321438 | 0.015469 |
3 | 0.434531 | 0.103644 |
4 | 0.434531 | 0.015713 |
In [127]:
# lambda를 이용하는 방법
def add_two_number(a,b):
return a + b
df['add'] = df.apply(lambda x : add_two_number(x['age'], x['fare']),
axis = 1) # 행단위
df.head()
Out[127]:
age | fare | add | |
---|---|---|---|
0 | 22.0 | 7.2500 | 29.2500 |
1 | 38.0 | 71.2833 | 109.2833 |
2 | 26.0 | 7.9250 | 33.9250 |
3 | 35.0 | 53.1000 | 88.1000 |
4 | 35.0 | 8.0500 | 43.0500 |
map()¶
In [134]:
# map 특정한 컬럼에 적용
import math
def log_e(x):
return math.log(x) if x != 0 else 0
df['log fare'] = df['fare'].map(log_e)
df
Out[134]:
age | fare | add | log fare | |
---|---|---|---|---|
0 | 22.0 | 7.2500 | 29.2500 | 1.981001 |
1 | 38.0 | 71.2833 | 109.2833 | 4.266662 |
2 | 26.0 | 7.9250 | 33.9250 | 2.070022 |
3 | 35.0 | 53.1000 | 88.1000 | 3.972177 |
4 | 35.0 | 8.0500 | 43.0500 | 2.085672 |
... | ... | ... | ... | ... |
886 | 27.0 | 13.0000 | 40.0000 | 2.564949 |
887 | 19.0 | 30.0000 | 49.0000 | 3.401197 |
888 | NaN | 23.4500 | NaN | 3.154870 |
889 | 26.0 | 30.0000 | 56.0000 | 3.401197 |
890 | 32.0 | 7.7500 | 39.7500 | 2.047693 |
891 rows × 4 columns
applymap()¶
In [135]:
# applymap() 데이터 프레임 전체에 적용
def doubling(x):
return x*2
double_df = df.applymap(doubling)
double_df
Out[135]:
age | fare | add | log fare | |
---|---|---|---|---|
0 | 44.0 | 14.5000 | 58.5000 | 3.962003 |
1 | 76.0 | 142.5666 | 218.5666 | 8.533324 |
2 | 52.0 | 15.8500 | 67.8500 | 4.140045 |
3 | 70.0 | 106.2000 | 176.2000 | 7.944354 |
4 | 70.0 | 16.1000 | 86.1000 | 4.171344 |
... | ... | ... | ... | ... |
886 | 54.0 | 26.0000 | 80.0000 | 5.129899 |
887 | 38.0 | 60.0000 | 98.0000 | 6.802395 |
888 | NaN | 46.9000 | NaN | 6.309741 |
889 | 52.0 | 60.0000 | 112.0000 | 6.802395 |
890 | 64.0 | 15.5000 | 79.5000 | 4.095386 |
891 rows × 4 columns
Grouping¶
In [ ]:
import numpy as np
import pandas as pd
import seaborn as sns
df = sns.load_dataset('titanic')
In [26]:
df = df[['age','sex','class','fare','survived']]
df.head()
Out[26]:
age | sex | class | fare | survived | |
---|---|---|---|---|---|
0 | 22.0 | male | Third | 7.2500 | 0 |
1 | 38.0 | female | First | 71.2833 | 1 |
2 | 26.0 | female | Third | 7.9250 | 1 |
3 | 35.0 | female | First | 53.1000 | 1 |
4 | 35.0 | male | Third | 8.0500 | 0 |
In [27]:
grouped = df.groupby(['class'])
grouped
Out[27]:
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x00000232F258C220>
그룹은 일반적인 방법으로 내용을 확인할 수 없다.
In [30]:
for key, group in grouped:
print('key:', key)
display(group)
key: First
age | sex | class | fare | survived | |
---|---|---|---|---|---|
1 | 38.0 | female | First | 71.2833 | 1 |
3 | 35.0 | female | First | 53.1000 | 1 |
6 | 54.0 | male | First | 51.8625 | 0 |
11 | 58.0 | female | First | 26.5500 | 1 |
23 | 28.0 | male | First | 35.5000 | 1 |
... | ... | ... | ... | ... | ... |
871 | 47.0 | female | First | 52.5542 | 1 |
872 | 33.0 | male | First | 5.0000 | 0 |
879 | 56.0 | female | First | 83.1583 | 1 |
887 | 19.0 | female | First | 30.0000 | 1 |
889 | 26.0 | male | First | 30.0000 | 1 |
216 rows × 5 columns
key: Second
age | sex | class | fare | survived | |
---|---|---|---|---|---|
9 | 14.0 | female | Second | 30.0708 | 1 |
15 | 55.0 | female | Second | 16.0000 | 1 |
17 | NaN | male | Second | 13.0000 | 1 |
20 | 35.0 | male | Second | 26.0000 | 0 |
21 | 34.0 | male | Second | 13.0000 | 1 |
... | ... | ... | ... | ... | ... |
866 | 27.0 | female | Second | 13.8583 | 1 |
874 | 28.0 | female | Second | 24.0000 | 1 |
880 | 25.0 | female | Second | 26.0000 | 1 |
883 | 28.0 | male | Second | 10.5000 | 0 |
886 | 27.0 | male | Second | 13.0000 | 0 |
184 rows × 5 columns
key: Third
age | sex | class | fare | survived | |
---|---|---|---|---|---|
0 | 22.0 | male | Third | 7.2500 | 0 |
2 | 26.0 | female | Third | 7.9250 | 1 |
4 | 35.0 | male | Third | 8.0500 | 0 |
5 | NaN | male | Third | 8.4583 | 0 |
7 | 2.0 | male | Third | 21.0750 | 0 |
... | ... | ... | ... | ... | ... |
882 | 22.0 | female | Third | 10.5167 | 0 |
884 | 25.0 | male | Third | 7.0500 | 0 |
885 | 39.0 | female | Third | 29.1250 | 0 |
888 | NaN | female | Third | 23.4500 | 0 |
890 | 32.0 | male | Third | 7.7500 | 0 |
491 rows × 5 columns
특정 그룹만 가지고 오기
In [34]:
third_group = grouped.get_group('Third')
third_group
Out[34]:
age | sex | class | fare | survived | |
---|---|---|---|---|---|
0 | 22.0 | male | Third | 7.2500 | 0 |
2 | 26.0 | female | Third | 7.9250 | 1 |
4 | 35.0 | male | Third | 8.0500 | 0 |
5 | NaN | male | Third | 8.4583 | 0 |
7 | 2.0 | male | Third | 21.0750 | 0 |
... | ... | ... | ... | ... | ... |
882 | 22.0 | female | Third | 10.5167 | 0 |
884 | 25.0 | male | Third | 7.0500 | 0 |
885 | 39.0 | female | Third | 29.1250 | 0 |
888 | NaN | female | Third | 23.4500 | 0 |
890 | 32.0 | male | Third | 7.7500 | 0 |
491 rows × 5 columns
각 그룹에 대한 집계함수 사용하기
In [36]:
my_mean = grouped.mean() # 숫자에 대한 컬럼만.
my_mean
Out[36]:
age | fare | survived | |
---|---|---|---|
class | |||
First | 38.233441 | 84.154687 | 0.629630 |
Second | 29.877630 | 20.662183 | 0.472826 |
Third | 25.140620 | 13.675550 | 0.242363 |
두 개 이상의 컬럼에 대해서 그룹화
In [38]:
grouped = df.groupby(['class','sex'])
Out[38]:
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x00000232F30D2940>
In [41]:
for key, group in grouped :
print(key)
display(group.head(3))
('First', 'female')
age | sex | class | fare | survived | |
---|---|---|---|---|---|
1 | 38.0 | female | First | 71.2833 | 1 |
3 | 35.0 | female | First | 53.1000 | 1 |
11 | 58.0 | female | First | 26.5500 | 1 |
('First', 'male')
age | sex | class | fare | survived | |
---|---|---|---|---|---|
6 | 54.0 | male | First | 51.8625 | 0 |
23 | 28.0 | male | First | 35.5000 | 1 |
27 | 19.0 | male | First | 263.0000 | 0 |
('Second', 'female')
age | sex | class | fare | survived | |
---|---|---|---|---|---|
9 | 14.0 | female | Second | 30.0708 | 1 |
15 | 55.0 | female | Second | 16.0000 | 1 |
41 | 27.0 | female | Second | 21.0000 | 0 |
('Second', 'male')
age | sex | class | fare | survived | |
---|---|---|---|---|---|
17 | NaN | male | Second | 13.0 | 1 |
20 | 35.0 | male | Second | 26.0 | 0 |
21 | 34.0 | male | Second | 13.0 | 1 |
('Third', 'female')
age | sex | class | fare | survived | |
---|---|---|---|---|---|
2 | 26.0 | female | Third | 7.9250 | 1 |
8 | 27.0 | female | Third | 11.1333 | 1 |
10 | 4.0 | female | Third | 16.7000 | 1 |
('Third', 'male')
age | sex | class | fare | survived | |
---|---|---|---|---|---|
0 | 22.0 | male | Third | 7.2500 | 0 |
4 | 35.0 | male | Third | 8.0500 | 0 |
5 | NaN | male | Third | 8.4583 | 0 |
In [44]:
class_sex_survived = df.groupby(['class','sex']).mean()['survived']
In [45]:
class_sex_survived
Out[45]:
class sex First female 0.968085 male 0.368852 Second female 0.921053 male 0.157407 Third female 0.500000 male 0.135447 Name: survived, dtype: float64
group에 대한 filtering
In [46]:
grouped = df.groupby(['class'])
grouped_filter = grouped.filter(lambda x : len(x)>300) #len(dataframe): 행의 개수
grouped_filter
Out[46]:
age | sex | class | fare | survived | |
---|---|---|---|---|---|
0 | 22.0 | male | Third | 7.2500 | 0 |
2 | 26.0 | female | Third | 7.9250 | 1 |
4 | 35.0 | male | Third | 8.0500 | 0 |
5 | NaN | male | Third | 8.4583 | 0 |
7 | 2.0 | male | Third | 21.0750 | 0 |
... | ... | ... | ... | ... | ... |
882 | 22.0 | female | Third | 10.5167 | 0 |
884 | 25.0 | male | Third | 7.0500 | 0 |
885 | 39.0 | female | Third | 29.1250 | 0 |
888 | NaN | female | Third | 23.4500 | 0 |
890 | 32.0 | male | Third | 7.7500 | 0 |
491 rows × 5 columns
반응형
'Programming > Pandas' 카테고리의 다른 글
[pandas] read_csv 'utf-8' error (1) | 2022.03.21 |
---|---|
[Pandas] Movie Lens Data를 이용한 EDA 실습 (1) | 2022.03.21 |
[pandas] DataFrame Indexing & Slicing (0) | 2022.03.17 |
[pandas] 여러가지 resource를 이용하여 DataFrame 생성하기 (csv, sql, api, json) (0) | 2022.03.17 |
[pandas] 데이터 조작 및 분석을 위한 python module - pandas (0) | 2022.03.17 |