9. Multiple filter criteria to DataFrame
C++ 에서 |는 비트연산자의 or을 의미하고, ||가 논리연산자의 or 을 의미하지만,
파이썬은 |가 논리연산자 or을 의미합니다. 또는 or이라고 적어도 됩니다.
and는 &, and로 표시합니다.
"상영시간이 200이상이거나 장르가 드라마인 영화목록"
movies[(movies.duration >= 200) | (movies.genre == 'Drama')]
select *
from movies
where movies.duration >= 200 or movies.genre == 'Drama'
movies[(movies.genre == 'Crime') | (movies.genre == 'Drama') | (movies.genre == 'Action')]
여러개의 or 조건이 있어서 이렇게 번거로운 상황이 발생할 때,
pandas는 쉬운 기능을 제공합니다.
movies[movies.genre.isin(['Crime', 'Drama', 'Action'])]
이 둘은 완전히 똑같습니다.
10. Questions, Describe()
1) csv파일을 불러올 수 있는 가장 빠른 방법
ufo = pd.read_csv('http://bit.ly/uforeports', nrow=3)
가장 위의 3개의 행만 불러옵니다.
전체를 불러오는 것은 아니지만, 대략적인 데이터의 구조를 파악할수 있습니다.
2) dataframe을 for문에서 이용하는 방법
for index, row in ufo.iterrows():
print(index, row.City, row.State)
3) 데이터에서 non-numeric 타입 열만 제거하는 방법
drinks = pd.read_csv('http://bit.ly/drinksbycountry')
drinks.dtypes
>>
country object
beer_servings int64
spirit_servings int64
wine_servings int64
total_litres_of_pure_alcohol float64
continent object
dtype: object
import numpy as np
drinks.select_dtypes(include=[np.number]).dtypes
>>
beer_servings int64
spirit_servings int64
wine_servings int64
total_litres_of_pure_alcohol float64
dtype: object
4) .describe() 사용법
drinks.describe() # default는 numeric 타입의 모든 열을 반환한다.
drinks.describe(include='all') # 모든 열을 반환한다.
drinks.describe(include=['object', 'float']) # 특정 타입의 열을 반환한다.
11. Axis 사용법
drinks.mean(axis=1) # 의미있는(meaningful) 수치가 아니다.
drinks.mean(axis=0) # default는 axis=0
axis = 0 (default) : 각각의 column에 대해 모든 row에 대한 평균을 구합니다. (결과 column개)
axis = 1 : 각각의 row에 대해 모든 column에 대한 평균을 구합니다. (결과 row개)
12. String Method
orders['item_name'].str.upper()
orders[orders['item_name'].str.contains('Chicken')]
orders['choice_description'].str.replace('[', '').str.replace(']','')
orders['choice_description'].str.replace('[\[\]]','') # Regular expression
이 이외에도 slice() 등 스트링을 다루는 method 는 많습니다.
13. Series에서 Data type 변경
대표적으로 string으로 되어있는 숫자를 int나 float으로 바꾸고 싶을 때 쓰입니다.
drinks['beer_servings'] = drinks['beer_servings'].astype(float)
데이터 불러올 때부터 타입을 바꿀 수도 있습니다.
drinks = pd.read_csv('http://bit.ly/drinksbycountry', dtype={'beer_servings':float})
drinks.dtypes
orders['item_price'].str.replace('$', '').astype(float).mean()
"$2.99 " 에서 $를 없애고 float형으로 바꾼뒤, 평균을 구합니다.
orders['item_name'].str.contains('Chicken').astype(int).head()
"Chicken"을 포함하는 문자열이 있으면 True, 아니면 False로 나올 텐데,
이것들을 int형 즉, 1과 0으로 바꾸어주어 계산할 수 있게 도와줍니다.
14. Groupby
aggregation function으로 count, mean, max, min, sum 등이 있습니다.
예제
drinks.groupby('continent')['beer_servings'].mean()
>>
continent
Africa 61.471698
Asia 37.045455
Europe 193.777778
North America 145.434783
Oceania 89.687500
South America 175.083333
Name: beer_servings, dtype: float64
beer_servings 열에서 continent별로 평균을 구한 결과가 나옵니다.
SQL로 표현해 봅시다.
select continent, min(beer_servings)
from drinks
group by continent
위결과는 아래 코드에서 Africa를 바꾸어 Asia, ..., South America 까지 일일이 한작업을 한번에 보여줍니다.
drinks[drinks['continent'] == 'Africa']['beer_servings'].mean()
여러개의 aggregation function을 한꺼번에 써봅시다.
drinks.groupby('continent').beer_servings.agg(['count', 'min', 'max', 'sum'])
>>
count min max sum
continent
Africa 53 0.0 376.0 3258.0
Asia 44 0.0 247.0 1630.0
Europe 45 0.0 361.0 8720.0
North America 23 1.0 285.0 3345.0
Oceania 16 0.0 306.0 1435.0
South America 12 93.0 333.0 2101.0
이번엔 표를 그래프로 바꾸어봅시다.
drinks.groupby('continent').mean()
>>
beer_servings spirit_servings wine_servings total_litres_of_pure_alcohol
continent
Africa 61.471698 16.339623 16.264151 3.007547
Asia 37.045455 60.840909 9.068182 2.170455
Europe 193.777778 132.555556 142.222222 8.617778
North America 145.434783 165.739130 24.521739 5.995652
Oceania 89.687500 58.437500 35.625000 3.381250
South America 175.083333 114.750000 62.416667 6.308333
%matplotlib inline
drinks.groupby('continent').mean().plot(kind='bar')
15. Explore Pandas Series
movies.dtypes
>>
star_rating float64
title object
content_rating object
genre object
duration int64
actors_list object
dtype: object
movies 테이블의 각 열마다 데이터 타입을 확인해봅시다.
genre는 string값인데, object로 표시가 됩니다.
movies.genre.describe()
>>
count 979
unique 16
top Drama
freq 278
Name: genre, dtype: object
object 타입은 count, unique, top, freq 정보를 알려주는군요.
duration 열은 int값입니다.
movies.duration.describe()
>>
count 979.000000
mean 120.979571
std 26.218010
min 64.000000
25% 102.000000
50% 117.000000
75% 134.000000
max 242.000000
Name: duration, dtype: float64
이에 대해서는 count, mean, std, min, ... 등 여러값을 보여주네요.
movies.genre.value_counts()
movies.genre.value_counts(normalize=True).head()
movies.genre.unique()
movies.genre.nunique()
%matplotlib inline
movies.genre.value_counts().plot(kind='bar')
movies.duration.mean()
movies.duration.value_counts()
movies.duration.plot(kind='hist')
다양한 값을 일일이 확인해 볼 수도있고,
matplotlib을 통해 bar나 histogram형식의 그래프도 출력해볼 수 있습니다.
각각의 genre(행)마다, content_rating(열)을 파악하고 싶다면, .crosstab()을 이용하면 됩니다.
pd.crosstab(movies.genre, movies.content_rating)
16. 결측값(Missing Value)
ufo.tail() # NaN은 결측값을 나타낸다.
>>
City Colors Reported Shape Reported State Time
18236 Grant Park NaN TRIANGLE IL 12/31/2000 23:00
18237 Spirit Lake NaN DISK IA 12/31/2000 23:00
18238 Eagle River NaN NaN WI 12/31/2000 23:45
18239 Eagle River RED LIGHT WI 12/31/2000 23:45
18240 Ybor NaN OVAL FL 12/31/2000 23:59
ufo.isnull().tail()
ufo.notnull().tail()
ufo.isnull().sum() # 열마다 결측값 개수를 의미
ufo[ufo.City.isnull()] ## City열에서 NaN 포함된 행만 select
ufo.dropna(how='all').shape # 모든 열의 값이 NaN인 행을 삭제
ufo.dropna(how='any').shape # NaN이 하나라도 있는 행은 삭제
ufo.dropna(subset=['City', 'Shape Reported'], how='all').shape # 이 두열에서 모두 NaN이 있는 행을 삭제
ufo['Shape Reported'].fillna(value='VARIOUS', inplace=True) #Various 값을 모두 NaN으로 채운다.
ufo['Shape Reported'].value_counts(dropna=False) #dropna=True가 기본값이고, True면 NaN은 무시하고 count한다.
missing value를 이용해서, dropna로 해당 열이나 행을 제거할 수 있다.
17. Pandas Index (Part 1)
drinks.index # index는 모든 DataFrame의 속성으로 있고, 열에 포함되지 않는다.
drinks.columns
drinks.shape
# Index기능: Identification
drinks[drinks.continent=='South America']
drinks.loc[23, 'beer_servings'] # 인덱스를이용해서 해당 열, 행의 원소찾기
# Index를 다른 칼럼으로 바꾸기
drinks.set_index('country', inplace=True)
drinks.index
drinks.columns
drinks.shape
drinks.loc['Brazil', 'beer_servings']
# Index 이름 제거
drinks.index.name = None
# Index 이름 다시 생성 후, Index(숫자) 다시 생성
drinks.index.name = 'country'
drinks.reset_index(inplace=True)
.describe()를 이용한 인덱싱 응용방법을 봅시다.
drinks.describe()
>>
beer_servings spirit_servings wine_servings total_litres_of_pure_alcohol
count 193.000000 193.000000 193.000000 193.000000
mean 106.160622 80.994819 49.450777 4.717098
std 101.143103 88.284312 79.697598 3.773298
min 0.000000 0.000000 0.000000 0.000000
25% 20.000000 4.000000 1.000000 1.300000
50% 76.000000 56.000000 8.000000 4.200000
75% 188.000000 128.000000 59.000000 7.200000
max 376.000000 438.000000 370.000000 14.400000
drinks.describe().index
>>
Index(['count', 'mean', 'std', 'min', '25%', '50%', '75%', 'max'], dtype='object')
drinks.describe().columns
>>
Index(['beer_servings', 'spirit_servings', 'wine_servings',
'total_litres_of_pure_alcohol'],
dtype='object')
drinks.describe().loc['25%', 'beer_servings']
20.0
18. Pandas Index (Part 2)
drinks.set_index('country', inplace=True)
drinks.continent.value_counts()
>>
Africa 53
Europe 45
Asia 44
North America 23
Oceania 16
South America 12
Name: continent, dtype: int64
drinks.continent.value_counts().values
>>
array([53, 45, 44, 23, 16, 12], dtype=int64)
drinks.continent.value_counts().sort_values() # Descending order
drinks.continent.value_counts().sort_index() # Ascending order
해당하는 row index에 짝이 있으면, 연산을 하고, 아니면 NaN을 반환합니다.
people = pd.Series([3000000, 85000], index=['Albania', 'Andorra'], name='population')
drinks.beer_servings * people
>>
Afghanistan NaN
Albania 267000000.0
Algeria NaN
Andorra 20825000.0
Angola NaN
...
Venezuela NaN
Vietnam NaN
Yemen NaN
Zambia NaN
Zimbabwe NaN
Length: 193, dtype: float64
.concat() 아래와 같이 하면 right outer join과 비슷한 것 같습니다.
pd.concat([drinks, people], axis=1).head()
>>
beer_servings spirit_servings wine_servings total_litres_of_pure_alcohol continent population
Afghanistan 0.0 0 0 0.0 Asia NaN
Albania 89.0 132 54 4.9 Europe 3000000.0
Algeria 25.0 0 14 0.7 Africa NaN
Andorra 245.0 138 312 12.4 Europe 85000.0
Angola 217.0 57 45 5.9 Africa NaN
population 열이 원래 테이블 오른쪽에 생기고, 알맞은 짝의 row index에만 값이 들어가있습니다.
19. Select multiple rows and columns
1) loc
ufo.loc[0, :] # 0번 row를 뽑아서 Series로 만들어줌
ufo.loc[0:2, :] # 0, 1, 2번 row를 뽑아서 dataframe로 만들어줌
ufo.loc[0:2] # 비추: 파이썬 코드는 명시적(Explicit)인 것이 좋아서 :를 쓰자.
ufo.loc[0:2, 'City':'State']
ufo.head(3).drop('Time', axis=1) # 이렇게 하는 것보다 loc을 사용하는 것이 작성력, 가독성에 더 도움이됨
ufo[ufo.City=='Oakland']
ufo.loc[ufo.City=='Oakland', :] # 이것이 조금 더 explict하다. 조금 더 safe하다
2) iloc
ufo.iloc[:, 0:4] # index를 통해 접근
ufo.iloc[0:3, :] # loc은 0:3하면 3까지 포함하지만, iloc은 3은 배제한다.
ufo[['City', 'State']]
ufo.loc[:, ['City', 'State']] # 위에 보다 이렇게 쓰는 것을 권장(Explicit)
ufo[0:2]
ufo.iloc[0:2, :] # 위에 보다 이렇게 쓰는 것을 권장(Explicit)
3) ix (will be deprecated) position(숫자), label(이름, 스트링)을 병행해서 사용
drinks = pd.read_csv('http://bit.ly/drinksbycountry', index_col='country')
>>
beer_servings spirit_servings wine_servings total_litres_of_pure_alcohol continent
country
Afghanistan 0 0 0 0.0 Asia
Albania 89 132 54 4.9 Europe
Algeria 25 0 14 0.7 Africa
Andorra 245 138 312 12.4 Europe
Angola 217 57 45 5.9 Africa
drinks.ix['Albania', 0]
drinks.ix[1, 'beer_servings']
drinks.ix['Albania':'Andorra', 0:2]
ufo.ix[0:2, 0:2] # position(0, 1, 2 다나옴)과 label(2는 배제)을 동시에 사용할 때만 사용권장, 아니면 헷갈림, 그리고 ix는 deprecated될것임.
20. Inplace Parameter
inplace=False 디폴트값인 이유는, 기존 데이터를 덮어씌우는 작업이기 때문에,
False상태로 여러 번 시도해 본 후,
하는 작업을 확정짓고 True를 적어주어서 덮어씌우는 작업을 합니다.
ufo.set_index('Time', inplace=True)
# ufo = ufo.set_index('Time') # 복사되고 할당하므로 비효율적.
inplace=True를 설정하기 전에는 잘 모르는 method도 여러번 실험해 볼 수 있다는 데에 장점이 있습니다.
ufo.fillna(method='bfill').head()
ufo.fillna(method='ffill').head()
[참고 - Data School https://www.youtube.com/watch?v=-NbY7E9hKxk&list=PL5-da3qGB5ICCsgW1MxlZ0Hq8LL5U3u9y&index=32]
'ML, DL > Data Analysis' 카테고리의 다른 글
R 데이터 타입, 그래픽, 데이터 마트, 결측값, 이상값 (77) | 2020.08.25 |
---|---|
[Pandas] Part 4. Duplicate, SettingWithCopyWarnings, Display options, Apply fuction, MultiIndex (1103) | 2019.10.12 |
[Pandas] Part 3. Dataframe smaller and faster, Dummy, Dates and times, (981) | 2019.10.12 |
[Pandas] Part 1. DataFrame, Series, Rename, Remove, Sort, Filter (961) | 2019.10.12 |
[Tutorial] scikit-learn과 pandas사용해서 kaggle submission 파일 만들기 (965) | 2019.10.11 |
댓글