-
Python 기초 공부 - 6 (Pandas)Programming/Python 2021. 3. 8. 19:42반응형
python : 문자열 처리
- 검색, 분리(split), 추출, 대체, 결합, 공백처리
- 문자열의 기본자료구조는 배열 (1차원 배열)정규표현식 (regular expression) : re => 모든 언어에서 똑같은 방식으로 처리
- 패턴으로 처리smiles = "C(=N)(N)N.C(=0)(0)0" # 1차원 배열 print(smiles[0]) print(smiles[1]) print(smiles[-1]) print(smiles[1:5]) print(smiles[10:-4])
C
(
0
(=N)
C(=0)# 단어찾기 s = "That that is is that that is" print(s.count('t')) s = s.lower() print(s.count("that")) s.find("that") # 단어별 s.find("is") s.find(" ")
7
4
4# ASCII code 95 = a print('C:\\nowhere') print(r'C:\\nowhere') # 정규표현식 # 3버전은 기본적으로 유니코드 print(u'Hello, world!') # unicode 2.7 버전
C:\nowhere
C:\\nowhere
Hello, world!# pandas 도 문자열 함수 지원 => 후처리가 편리 import pandas as pd monte = pd.Series(['Graham Chapman', 'John Cleese', 'Terry Gilliam', 'Eric Idle', 'Terry Jones', 'Michael Palin'])
monte.str.lower()
0 graham chapman
1 john cleese
2 terry gilliam
3 eric idle
4 terry jones
5 michael palin
dtype: objectmonte.str.len()
0 14
1 11
2 13
3 9
4 11
5 13
dtype: int64monte.str.startswith('T')
0 False
1 False
2 True
3 False
4 True
5 False
dtype: boolmonte.str.split()
0 [Graham, Chapman]
1 [John, Cleese]
2 [Terry, Gilliam]
3 [Eric, Idle]
4 [Terry, Jones]
5 [Michael, Palin]
dtype: object# 정규표현식 # []: 선택, + : 여러개 monte.str.extract('([A-Za-z]+)', expand=False)
0 Graham
1 John
2 Terry
3 Eric
4 Terry
5 Michael
dtype: object# ^ : 처음부터, [^] : 부정, $ : 끝 monte.str.findall(r'^[^AEIOU].*[^aeiou]$') # 처음이 AEIOU로 시작하지 않고, 끝이 aeiou가 아닌 것 # 자세한 내용은 아래 링크 참조 # http://pythonstudy.xyz/python/article/401-%EC%A0%95%EA%B7%9C-%ED%91%9C%ED%98%84%EC%8B%9D-Regex
0 [Graham Chapman]
1 []
2 [Terry Gilliam]
3 []
4 [Terry Jones]
5 [Michael Palin]
dtype: object# 문자열 찾기 (정규표현식) import re text = "문의사항이 있으면 032-232-3245으로 연락주시기 바랍니다.or 010-456-4658" # \d : 숫자한개 # {} : 개수 # 패턴을 컴파일 regex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') regex = re.compile(r'(\d{3})-(\d{3}-\d{4})') # 하나의 단위로 {} matchobj = regex.search(text) phonenumber = matchobj.group() # 여러개가 나오는 상황 print(phonenumber)
032-232-3245
# boolean 형태로 검색해서 찾기 import numpy as np s4 = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat']) s4.str.contains('A', na=False)
0 True
1 False
2 False
3 True
4 False
5 False
6 True
7 False
8 False
dtype: boolfrom pandas import Series, DataFrame import pandas as pd import numpy as np import re data={'Dave':'iadslba@naver.com', 'Steve':'steve@gmail.com', 'Rob':'rob', 'Wes':np.nan} data=Series(data) print(data)
Dave iadslba@naver.com
Steve steve@gmail.com
Rob rob
Wes NaN
dtype: object
print(data.isnull()) print("네이버", data.str.contains('naver'))
Dave False
Steve False
Rob False
Wes True
dtype: bool
네이버 Dave True
Steve False
Rob False
Wes NaN
dtype: object# r : regular expression # 정규표현식에서의 .은 한개, 진짜 .을 표현하려면 \. # match의 결과값은 True/False pattern = r'[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]' matches = data.str.match(pattern, flags=re.IGNORECASE) # 대소문자 구분없이
print("matches 결과 :", matches) matches = data.str.findall(pattern, flags=re.IGNORECASE) print("findall 결과 :", matches)
matches 결과 : Dave True
Steve True
Rob False
Wes NaN
dtype: object
findall 결과 : Dave [iadslba@naver.c]
Steve [steve@gmail.c]
Rob []
Wes NaN
dtype: object# one-hot-encoding s = pd.Series(['a','a|b', np.nan, 'a|c']) print(s) # 행은 관측 숫자, 열은 변수 s.str.get_dummies(sep='|')
0 a
1 a|b
2 NaN
3 a|c
dtype: object
a b c
0 1 0 0
1 1 1 0
2 0 0 0
3 1 0 1# 함수를 매개변수로 전달할 때는 함수 실행이 아니고 함수 위치를 전달하는 것 df = pd.DataFrame(['한글', '미국', '일본?'], columns=['text']) # 파생변수 df['text_length'] = df['text'].map(len) # 시리즈에 함수 적용 print(df)
text text_length
0 한글 2
1 미국 2
2 일본? 3data = {'name':['하늘이','찬호박','우리야','함께가','하성공'], 'age':[40,50,30,20,70], 'preScore':[14,28,39,25,32], 'postScore':[20, 90, 55, 65, 79]} df = pd.DataFrame(data, columns = ['name','age','preScore','postScore']) df
# 4줄짜리 코드 print(df['age'].count()) print(df['preScore'].mean()) print(df['preScore'].std()) print(df['preScore'].cumsum()) # --- 한줄로 해결 print() print("데이터 설명") print(df['preScore'].describe()) print("데이터 끝")
5
27.6
9.235799911215056
0 14
1 42
2 81
3 106
4 138
Name: preScore, dtype: int64
데이터 설명
count 5.0000
mean 27.6000
std 9.2358
min 14.0000
25% 25.0000
50% 28.0000
75% 32.0000
max 39.0000
Name: preScore, dtype: float64
데이터 끝print(df['preScore'].var()) print(df['preScore'].std()) print(df['preScore'].skew()) # 왜도 0 좌우대칭 print(df['preScore'].kurt()) # 첨도 3 정규분포 # 왜도는 치우쳐진 정도(+면 왼쪽으로), 첨도는 뾰족한 정도(+면 뾰족) # 왜도와 첨도가 안정적이면 정규분포를 가정할 수 있음 # https://m.blog.naver.com/PostView.nhn?blogId=moses3650&logNo=220880815585&proxyReferer=https%3A%2F%2Fwww.google.com%2F
85.30000000000001
9.235799911215056
-0.5110345040062979
0.8509652849263816import pandas as pd import numpy as np df = pd.DataFrame({'two' : pd.Series(np.random.randn(3), index=['c', 'b', 'a']), 'one' : pd.Series(np.random.randn(4), index=['d', 'b', 'c', 'a']), 'three' : pd.Series(np.random.randn(3), index=['b', 'c', 'd'])}) df
df.loc[:'b',:'one']
row = df.iloc[1] # 한 행 데이터 print(row)
two -0.625601
one -0.454957
three -1.473806
Name: b, dtype: float64column = df['two'] # 한 열 데이터 print(column)
a -0.946361
b -0.549165
c 0.009467
d NaN
Name: two, dtype: float64판다스는 열중심 - 열끼리의 상관계수
print(df.corr()) # correlation (상관계수 행렬) # 행과 열의 이름은 열변수 이름 # - : 부적상관 (역상관) # + : 정적상관 # 상관계수행렬은 정방행렬이면서 대칭행렬 => 고유값 분해 : 고유값(값 3개) + 고유벡터(3X3) 방향축간에 서로 직교 # 여기서 주성분 분석이 나옴! (고유값이 가장 큰 축이 추성분, 작은 것들은 빼는 것이 변수선택법 85% 정도만 남기고 변수 버림)
two one three
two 1.000000 0.687497 -1.00000
one 0.687497 1.000000 -0.55333
three -1.000000 -0.553330 1.00000
two one three
two 0.230574 0.103110 -0.331978
one 0.103110 0.072693 -0.134150
three -0.331978 -0.134150 0.539151# 상관계수 행렬 # 다수의 변수간 상관관계 파악할 때 # 회귀분석에서 종속변수와 독립변수간 선형관계를 파악하거나 # 독립변수간 다중공선성을 파악하려고 할 때 사용하는 분석기법 # https://rfriend.tistory.com/tag/%EC%83%81%EA%B4%80%EA%B3%84%EC%88%98%20%ED%96%89%EB%A0%AC # 시각화 방법은 산점도 행렬 / 상관계수 행렬 plot (correlation matrix plot)
import pandas as pd lst = [[1,2,3,4,5,6,7], [10,15,20,25,50,55,60],[0,0,0,0,0,0,0],[-1,-20,-30,-45,-50,-55,-70]] df = pd.DataFrame(lst).T corr = df.corr(method='pearson') print(corr)
0 1 2 3
0 1.000000 0.966282 NaN -0.983120
1 0.966282 1.000000 NaN -0.917002
2 NaN NaN NaN NaN
3 -0.983120 -0.917002 NaN 1.000000# 공분산과 상관계수
# 두 개 이상의 서로 연관성을 갖는 자료 값의 집합들이나 혹은 확률 변수들의 관계를 나타내는 값
# heatmap과 같은 서술 통계 방법으로 묘사하거나 결합 확률 분포를 사용하여 정의import seaborn as sns import pandas as pd import scipy as sp import matplotlib as mpl import matplotlib.pylab as plt import numpy as np %matplotlib inline sns.set() sns.set_color_codes()
seaborn = 시각화 라이브러리
X = 10*np.random.randn(1000, 6) X
array([[ 14.04407801, 7.1103409 , -3.86595689, -13.00789291,
-11.11094085, -12.64901497],
[ 10.51946269, -8.41763573, -5.28104629, -15.12084608,
0.74894373, 5.62686195],
[ -6.04795292, 16.0864203 , 4.05851898, -2.78020106,
20.63188984, 4.91760841],
...,
[-16.72089346, 13.8303662 , 15.92333104, 19.47624157,
5.07710757, -9.00793982],
[ 4.14580223, -1.27679306, -0.4218097 , 3.48147417,
8.9224342 , -10.5354439 ],
[ -5.50526103, 12.94422897, 17.01463157, 23.3407906 ,
6.75389859, -22.9241085 ]])# 공분산을 구하는 방법 두가지 C = np.cov(X, rowvar=0) (X-X.mean()).T.dot((X-X.mean()))/(len(X)-1)
array([[105.49965872, -0.83937216, 0.11596065, -0.7921198 ,
-1.87393213, 2.21192576],
[ -0.83937216, 104.94451983, 2.50883727, -0.75557596,
0.13060117, -2.48189517],
[ 0.11596065, 2.50883727, 99.67975659, -0.1115056 ,
-1.11046052, 2.67437667],
[ -0.7921198 , -0.75557596, -0.1115056 , 99.26666756,
-3.78445444, 1.6691171 ],
[ -1.87393213, 0.13060117, -1.11046052, -3.78445444,
98.98425047, 0.75223531],
[ 2.21192576, -2.48189517, 2.67437667, 1.6691171 ,
0.75223531, 97.30716689]])plt.figure(figsize=(12,6)) plt.imshow(C, interpolation="none") plt.colorbar() plt.grid(False)
# correlation 상관도 # 두 확률변수의 선형관계를 나타내는 척도 (pearson correlation) # correlation matrix # rowvar=0 => 행으로 쌓기 R = np.corrcoef(X, rowvar=0) R
array([[ 1. , -0.00797718, 0.00113079, -0.0077404 , -0.01833772,
0.02183095],
[-0.00797718, 1. , 0.02452952, -0.00740281, 0.0012814 ,
-0.02456016],
[ 0.00113079, 0.02452952, 1. , -0.00112096, -0.01117935,
0.0271548 ],
[-0.0077404 , -0.00740281, -0.00112096, 1. , -0.03817847,
0.01698293],
[-0.01833772, 0.0012814 , -0.01117935, -0.03817847, 1. ,
0.00766475],
[ 0.02183095, -0.02456016, 0.0271548 , 0.01698293, 0.00766475,
1. ]])plt.figure(figsize=(12,6)) plt.imshow(R, interpolation='none') plt.colorbar() plt.grid(False)
import statsmodels.api as sm data = sm.datasets.get_rdataset('anscombe') df = data.data df
plt.figure(figsize=(20,6)) plt.subplot(221) sns.regplot(x='x1', y='y1', data=df) plt.subplot(222) sns.regplot(x='x2', y='y2', data=df) plt.subplot(223) sns.regplot(x='x3', y='y3', data=df) plt.subplot(224) sns.regplot(x='x4', y='y4', data=df) plt.show()
x = np.linspace(-0.5, .5, 100) y = x**2 print(np.corrcoef(x,y)) plt.scatter(x,y)
[[1.00000000e+00 2.52533867e-16]
[2.52533867e-16 1.00000000e+00]]
<matplotlib.collections.PathCollection at 0x26aab6586a0># rank-based correlation x = "TGGAGGCAATGGCGGCCAGCA" y = "TGAGGGCCGGCGAGAATGGCA" mapping = dict(zip(['A','T','G','C'], range(4))) x = [mapping[i] for i in x] y = [mapping[i] for i in y]
sp.stats.spearmanr(x,y) # 스피어만의 순위 상관계수 ( 두 변수를 순위로 변환 후 순위에 대해 상관계쑤 구함)
SpearmanrResult(correlation=-0.07786173874795632, pvalue=0.7372715629763089)
sp.stats.kendalltau(x,y) # 켄달 토우의 순위 상관계수 ( 순위가 같은 짝 concordant의 수를 이용하여 계산 )
KendalltauResult(correlation=-0.06645435190240834, pvalue=0.7305031620485603)
print(df.cov()) # 공분산 행렬 (x-xbar)*(y-ybar)/ (n-1) *자유도에서 1을 빼주는 건 자기 자신은 선택이 아니기 때문
df1 = pd.DataFrame({'col':['foo', 0, np.nan]}) df2 = pd.DataFrame({'col':[np.nan, 0, 'foo']}, index=[2,1,0]) df3 = pd.DataFrame({'col':[1, 2, 3]}, index=[2,1,0]) df2
print(df3.sort_values(by=['col']))
col
2 1
1 2
0 3print(df2.sort_index())
col
0 foo
1 0
2 NaN# 인덱스
# index 행
# columns 열%matplotlib inline import seaborn as sns import matplotlib.pyplot as plt iris = sns.load_dataset('iris') iris.sepal_length[:20].plot(kind='bar', rot=0) # rot = 글씨 rotate plt.show()
iris.head()
# pandas io in pandas 검색 names = ['한국성','공하자','희망이','꿈꾼다','아리랑'] births = [25, 30, 38, 28, 31] BabyDataSet = list(zip(names, births)) print(BabyDataSet) df = pd.DataFrame(data = BabyDataSet, columns=['Names','Births']) print(df) # 인덱스 저장하면 열로 나타남, 그래서 index=False # 로딩할 때 인덱스로 열 지정이 가능 # header = 열 이름을 저장할지 df.to_csv('births2020.csv', index=False, header=True, encoding = "UTF-8") # 윈도우포맷이랑 리눅스포맷 다름름 Location = './births2020.csv' df = pd.read_csv(Location) print(df) df = pd.read_csv(Location, names=['Names', 'Births'], encoding="UTF-8")
[('한국성', 25), ('공하자', 30), ('희망이', 38), ('꿈꾼다', 28), ('아리랑', 31)]
Names Births
0 한국성 25
1 공하자 30
2 희망이 38
3 꿈꾼다 28
4 아리랑 31
Names Births
0 한국성 25
1 공하자 30
2 희망이 38
3 꿈꾼다 28
4 아리랑 31json 키-값 형태의 noSQL
pickle 메모리에 저장된 형태 그대로 올리고 받고
기본적인 csv 불러와서 기초 분석 진행
# 행이름 pim = pd.read_csv("diab.csv", index_col=0) # unnamed 없애주는 index_col=0 pim
pim.describe()
print(pim.apply(type))
pim.applymap(type).head(1)
pim.dtypes
npreg int64
glu int64
bp int64
skin int64
bmi float64
ped float64
age int64
type object
dtype: objectprint("데이터갯수", pim.count())
데이터갯수 npreg 332
glu 332
bp 332
skin 332
bmi 332
ped 332
age 332
type 332
dtype: int64print(pim.shape)
(332, 8)
print(pim[pim["bmi"]<30].shape) # bmi가 30보다 작은 행 갯수
(118, 8)
pim.mean() # 열별로 평균
npreg 3.484940
glu 119.259036
bp 71.653614
skin 29.162651
bmi 33.239759
ped 0.528389
age 31.316265
dtype: float64import matplotlib.pyplot as plt pim["bmi"].hist() # barplot(이산적) / histogram(부동소수점 float) plt.show() pim["bmi"].plot(kind="kde") # interpolation (보간법) plt.show()
pim.head()
pim.groupby("type") # DataFrameGroupBy 내부적으로 표현
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000001A718F64888>
# 집계함수 sum(), mean(), median(), max(), min(), last(), first() pim.groupby("type").mean()
pim.groupby("type").count()
group_by_type = pim.groupby("type") group_by_type.mean() group_by_type.std()
group_by_type.agg([np.mean, np.std])
print(np.mean(pim[pim["type"]=="Yes"]["skin"]))
32.88990825688074
print(np.std(pim[pim["type"]=="Yes"]["skin"]))
9.024268451930087
weather = pd.read_csv("we_2012.csv") weather
weather_2012_final = pd.read_csv("we_2012.csv") weather_2012_final.head()
index 지정하면 검색이 100배 빨라짐
시간데이터에서 Datetime Index를 만드는 방법# index 지정하면 검색이 100배 빨라짐 # 시간데이터에서 Datetime Index를 만드는 방법 date_range() # 일정한 주기와 기간을 정해서 생성할 때 to_datetime() # 기존에 있는 시간 데이터를 변환
index = pd.to_datetime(weather_2012_final["Date/Time"]) weather_2012_final.index = index weather_2012_final.head() # 똑같이 보이는데 질이 다름!
del(weather_2012_final["Date/Time"]) weather_2012_final.head()
weather_2012_final.shape
(8784, 7)
bigFilePath = "we_2012.csv" # 날짜 인덱스로 자동 변환해주고 # 대량의 데이터인 경우 chunksize chunker = pd.read_csv(bigFilePath, chunksize=1000, index_col="Date/Time", encoding="UTF-8") weather_2012_final = pd.concat([x for x in chunker], ignore_index=True)
print(weather_2012_final.describe()) weather_2012_final.dtypes
weather_2012_final['Temp (C)'].plot(figsize=(30,12)) weather_2012_final.boxplot()
print("결측치", weather_2012_final.count())
print(weather_2012_final.isnull().values.sum()) # null의 개수
0
print(weather_2012_final.isnull().any())
Temp (C) False
Dew Point Temp (C) False
Rel Hum (%) False
Wind Spd (km/h) False
Visibility (km) False
Stn Press (kPa) False
Weather False
dtype: boolweather_2012_final = weather_2012_final.dropna(axis=1, how='any') # 열방향 : 행삭제
f = lambda x: x.max() -x.min() print("함수 객체의 열 적용 (행방향)", weather_2012_final.apply(f)) # 문자열 포함이라 계산이 안됨
weather_2012_final.dtypes weather_2012_final_num = weather_2012_final.iloc[:,:6] print("함수 객체의 열 적용 (행방향)", weather_2012_final_num.apply(f))
함수 객체의 열 적용 (행방향) Temp (C) 56.30
Dew Point Temp (C) 52.90
Rel Hum (%) 82.00
Wind Spd (km/h) 83.00
Visibility (km) 48.10
Stn Press (kPa) 6.13
dtype: float64# ptp (point to point) : min-max print("함수 객체의 열 적용 (행방향)", weather_2012_final_num.apply(np.ptp))
함수 객체의 열 적용 (행방향) Temp (C) 56.30
Dew Point Temp (C) 52.90
Rel Hum (%) 82.00
Wind Spd (km/h) 83.00
Visibility (km) 48.10
Stn Press (kPa) 6.13
dtype: float64import glob import os import pandas as pd filePathList = glob.glob("./same__files/*.csv") print(filePathList) temp = os.path.basename(filePathList[0]) # 파일 확장자 print(temp)
['./same__files\\1763.csv', './same__files\\1764.csv', './same__files\\1765.csv', './same__files\\1766.csv', './same__files\\1767.csv', './same__files\\1768.csv', './same__files\\1769.csv', './same__files\\1770.csv', './same__files\\1771.csv', './same__files\\1772.csv'] 1763.csv
temp = os.path.splitext(temp)[0] print(temp) os.path.splitext(temp)
1763
('1763', '')# data_1763이라는 변수로 리딩 : vars() 메모리에 있는 변수들 for i in range(0, len(filePathList)): temp = os.path.basename(filePathList[i]) temp = os.path.splitext(temp)[0] vars()["data_" + str(temp)] = pd.read_csv(filePathList[i])
print(data_1763.head(3)) print(data_1770.shape)
ITE00100554 17630101 TMAX -36 Unnamed: 4 Unnamed: 5 E Unnamed: 7
0 ITE00100554 17630101 TMIN -50 NaN NaN E NaN
1 ITE00100554 17630102 TMAX -26 NaN NaN E NaN
2 ITE00100554 17630102 TMIN -40 NaN NaN E NaN
(729, 8)df = pd.read_csv("./sales.csv") df
df.dtypes
Customer Number int32
Customer Name object
2016 object
2017 object
Percent Growth object
Jan Units object
Month int64
Day int64
Year int64
Active object
dtype: object1. 정수 => 부동소수점으로 인식
2. $를 제거
3. %를 제거
4. 숫자에 문자 제거
5. Y:1, N:0 으로 boolean형으로 변경# astype으로 형변환 진행(int형으로) df['Customer Number'] = df['Customer Number'].astype("int")
df['2016'] = df['2016'].str.replace("$","") df['2016'] = df['2016'].str.replace(",","") df['2016'] = df['2016'].astype('float') df['2017'] = df['2017'].map(lambda x: x.replace("$","")) df['2017'] = df['2017'].map(lambda x :x.replace(",","")) df['2017'] = df['2017'].astype('float') #df['Percent Growth'] = df['Percent Growth'].str.replace("%","") def convert_percent(val): new_val = val.replace('%','') return float(new_val) / 100 df['Percent Growth'] = df['Percent Growth'].map(convert_percent)
df['Active'] = df['Active'] == 'Y'
df['Jan Units'] = pd.to_numeric(df['Jan Units'], errors='coerce') # ignore, raise
df.dtypes
Customer Number int32
Customer Name object
2016 float64
2017 float64
Percent Growth float64
Jan Units float64
Month int64
Day int64
Year int64
Active bool
dtype: object반응형'Programming > Python' 카테고리의 다른 글
Python 기초 공부 - 7 (numpy) (0) 2021.03.09 Python 기초 공부 - 8 (Pandas,numpy) (0) 2021.03.09 Python 기초 공부 - 5 (mariaDB 연동) (0) 2021.03.07 Python 기초 공부 - 4 (0) 2021.03.06 Python 기초 공부 - 3 (0) 2021.03.05