/////
Search
🧹

전처리

Archive
ETA
2025/12/22 → 2025/12/24
Main Task
Sub Task
메모
상태
Not started
생성 일시
2025/12/22 00:59
생성자
파일과 미디어
환경정보(enviroment)
분류코드
생산정보(production)
생육정보(grrowth)
에너지사용정보(energy)
전처리 과정
import pandas as pd import numpy as np import time energy = pd.read_csv(r"project_data_set\영어ver\22_energtinfo.csv", encoding="euc-kr",low_memory = False) environment = pd.read_csv(r"project_data_set\영어ver\22_enviroinfo2.csv", encoding="euc-kr",low_memory = False) growth = pd.read_csv(r"project_data_set\영어ver\22_growinfo.csv", encoding="euc-kr",low_memory = False) production = pd.read_csv(r"project_data_set\영어ver\22_proinfo.csv", encoding="euc-kr",low_memory = False) # 시각화시 한국어 안깨지게 하는 방법 import matplotlib.pyplot as plt plt.rcParams['font.family'] = 'Malgun Gothic' # 윈도우 기본 한글 폰트 plt.rcParams['axes.unicode_minus'] = False
Python
복사
# 원본데이터 정제하기 ------------------------------------------------------------------------------------- # 1.growth ## growth에서 itemCode 누락값 오른쪽으로 밀고 itemCode에 80300 채워넣고 itemCode 삭제하기 ### growth1에 itemCode 누락값이 있는'이삭줍는 알파고' 필터링 해주기 growth1 = growth[growth['farm_cde'] == '이삭줍는 알파고'] ### growth1의 칼럼 이동 기준 설정해주기 (growth1에서 itemCode 기준으로 오른쪽 1칸씩 밀어야하기때문에 이동기준 설정해줌) mask = growth1.columns[2:] ### growth1의 테이블에서 mask로 필터링해서 열기준으로 1칸씩 오른쪽으로 밀기 growth1[mask] = growth1[mask].shift(1, axis=1) ### growth2에 '이삭줍는 알파고'를 제외한 테이블 생성하기 growth2 = growth[growth['farm_cde'] != '이삭줍는 알파고'] ### 원본 growth 에 growth1과 growth2 수직으로 붙이기 ('이삭줍는 알파고' 열 이동한 growth1과 원본 growth에서의 '이삭줍는 알파고'를 제외한 값 붙이면 growth 원본값 완성됌) growth = pd.concat([growth1, growth2], ignore_index=True) ### growth['이삭줍은 알파고']에서 itemCode == 80300 가 아닌 결측치 대체하기 ### ※ fillna는 결측치 nan 전용 → loc 사용 (fillna → 비어있는 칸만 / loc → 비어있든 말든 조건 맞으면 다 바꿈) growth['itemCode'] = growth['itemCode'].fillna(80300) growth.sort_values('farm_cde') ### 현재 전체 데이터셋은 itemCode == 80300(토마토)로 모든 값이 토마토 생장과정에 필요한 데이터이므로, 동등한 조건임을 확인하고 itemCode 삭제함. growth = growth.drop(['itemCode'],axis=1) ------------------------------------------------------------------------------------- # 2.environment ## environment 에서 기호로 값이 작성된 fatrCode를 가독성을 높이기 위해 기호의 의미 추가하기 environment['FatrCode'] = environment['fatrCode'].replace({'TE':'외부온도', 'WD':'외부풍향', 'WS':'외부풍속', 'WP':'폭풍신호', 'RP':'강우신호', 'SR':'누적광', 'IR':'광량', 'T1':'온도1', 'T2':'온도2', 'TA':'평균온도', 'TB':'예비온도', 'HI':'습도', 'CI':'CO2', 'TP1':'난방관1온도', 'TP2':'난방관2온도', 'TQ':'이슬점온도', 'TH':'천창환기온도', 'TS':'난방설정온도', 'CL':'배지온도', 'EB':'배지EC', 'HL':'배지수분', 'EI':'(양액)공급EC', 'EO':'(양액)배약EC', 'PI':'(양액)공급PH', 'PO':'(양액)배액PH', 'EL':'토양EC', 'PL':'토양PH', 'CC01':'좌천장', 'CC02':'우천장', 'CC03':'좌측창', 'CC4':'우측창', 'CC5':'수평커튼1', 'CC6':'수평커튼2', 'CC7':'수평커튼3', 'CC8':'측커튼1', 'CC9':'측커튼2', 'CC10':'측커튼3', 'CC11':'제어벨브', 'CC12':'제어벨브', 'CC13':'CO2제어', 'CC14':'냉/난방기', 'CC15':'순환펌프1', 'CC16':'순환펌프2', 'CC17':'보조난방기', 'CC18':'훈증기', 'CC19':'유동팬', 'CC20':'배기팬', 'CC21':'보관등', 'CC22':'스프링클러', 'CC23':'분무', 'CC24':'양액기알람'}) ## 현재 전체 데이터셋은 itemCode == 80300(토마토)로 모든 값이 토마토 생장과정에 필요한 데이터이므로, 동등한 조건임을 확인하고 itemCode 삭제함. environment = environment.drop(['itemCode','classCode'],axis=1) #'classCode'는 FG(시설원예)를 뜻함. ------------------------------------------------------------------------------------- # 3.production ## production에서 itemGrade의 값 기준으로 ## 배꼽썩은과 - 1(True) (배꼽상품과:상품불가능)와 나머지 등급 - 0(False) (1~4등급,비상품과:상품가능)로 나눠주기 ### np.where(조건, 참일때값, 거짓일때값) = if문 production['상품유무'] = np.where((production['itemGrade'] == '배꼽썩음과'),1,0) -------------------------------------------------------------------------------------
Python
복사
# 분석 방향에 맞는 데이터로 정제하기 ------------------------------------------------------------------------------------- ''' 데이터 정제하기 : 현재 방향성에서 필요없는 칼럼 삭제하기 [현재 분석 방향성] 현 데이터를 활용하여 토마토의 생산성을 높인다. 토마토 생산성을 높이면서 배꼽썩음과가 나오지 않는 환경을 만들겠다. [분석 목표] 1. 배꼽썩음과가 나오는 환경을 분석하여 폐기량 줄이기 2. 토마토 생산성 1등급 생산 올리기 (+2~4등급, 비상품과) = 생산성의 총합을 구할 수 있으니 생육 정보의 데이터를 토대로 토마토 ''' ------------------------------------------------------------------------------------- # 현재 방향성에서 필요없는 칼럼 삭제하기 (분석 데이터 정제하기) ''' environment_df growth_df production_df 원본데이터 복제해서 이름으로 사용예정 ''' ------------------------------------------------------------------------------------- # environment # environment 사용할 데이터 복제 environment_df = environment.copy() ## 1. 현재 방향에서 토양에 관련된 데이터는 확인 후 삭제하기(sectCode의 CR 온실 환경 제어 시스템 값 관련으로 현재 분석방향성에 필요한 값인지 확인하는 과정) ###→ CC24 : 양액기알람 값은 모두 0.0으로 sectCode인 'CR'열을 삭제해도 무관함. c= (environment_df['fatrCode'] == 'CC24')&(environment_df['senVal'] != 0.0) c.sum() #CC24는 전부 0.0 ### sectCode의 'CR'에 속한 fartCode는 현재 분석방향성에 해당사항이 아닌 값이기 때문에 삭제하기 ''' 'CC01':'좌천장', 'CC02':'우천장', 'CC03':'좌측창', 'CC4':'우측창', 'CC5':'수평커튼1', 'CC6':'수평커튼2', 'CC7':'수평커튼3', 'CC8':'측커튼1', 'CC9':'측커튼2', 'CC10':'측커튼3', 'CC11':'제어벨브', 'CC12':'제어벨브', 'CC13':'CO2제어', 'CC14':'냉/난방기', 'CC15':'순환펌프1', 'CC16':'순환펌프2', 'CC17':'보조난방기', 'CC18':'훈증기', 'CC19':'유동팬', 'CC20':'배기팬', 'CC21':'보관등', 'CC22':'스프링클러', 'CC23':'분무', 'CC24':'양액기알람' ''' ### 앞서 말한 environment에서 현재 분석방향성에 해당사항이 아닌 값 삭제하기 mask = environment_df[environment_df['sectCode'] == 'CR'].index environment_df = environment_df.drop(mask) ## 2. 시계열데이터(날짜+시간)이므로 environment_df : measDate의 날짜 + 시간 형태를 날짜 칼럼과 시간 칼럼으로 2개로 나누기 environment_df['hour'] = environment_df['measDate'].dt.hour environment_df['measDate'] = environment_df['measDate'].dt.date ## 3. 식물에게 중요한 빛(광합성)을 중심으로 밤과 낮을 구별하는 시간 분리하기 ### hour에서 주간(일출~일몰 사이)과 야간(일몰~일출 사이)으로 나누기 → np.where(조건, 참일때값, 거짓일때값) = if문 hour = np.where((environment_df['hour'] >= 6) & (environment_df['hour'] < 18),'주간','야간') environment_df['주야'] = hour environment_df['주야'] = pd.Categorical(environment_df['주야'],categories=['주간', '야간'],ordered=True) ------------------------------------------------------------------------------------- # growth # growth 사용할 데이터 복제 growth_df = growth.copy() # 이상치 확인 growth_df.sort_values('measDate') # 동일 날짜 기준 4개의 온실에서의 토마토 생장측정값에서 이상치 발견 = 2022-09-26 이삭줍는 알파고 grwtLt << 이상치 확인 필요 ------------------------------------------------------------------------------------- # production # production 사용할 데이터 복제 production_df = production.copy() # production 에서 outtrn(수확 과중) 컬럼을 생산량으로 판단 (NaN과 0값 결측치 처리) production_df = production.dropna() production_df = production_df[production_df['outtrn'] != 0] production_df.reset_index(drop=True, inplace=True)
Python
복사
# farm_cde의 4개의 온실을 각각 나누기 (environment_df, growth_df, production_df = 전처리 끝난 테이블) ''' ~_df1 = 'Trigger' ~_df2 = '천지인술' ~_df3 = '토마토명가' ~_df4 = '이삭줍는 알파고' ''' ## environment_df environment_df1 = environment_df[environment_df['farm_cde'] == 'Trigger'] environment_df2 = environment_df[environment_df['farm_cde'] == '천지인술'] environment_df3 = environment_df[environment_df['farm_cde'] == '토마토명가'] environment_df4 = environment_df[environment_df['farm_cde'] == '이삭줍는 알파고'] ## growth_df growth_df1 = growth_df[growth_df['farm_cde'] == 'Trigger'] growth_df2 = growth_df[growth_df['farm_cde'] == '천지인술'] growth_df3 = growth_df[growth_df['farm_cde'] == '토마토명가'] growth_df4 = growth_df[growth_df['farm_cde'] == '이삭줍는 알파고'] ## production_df production_df1 = production_df[production_df['farm_cde'] == 'Trigger'] production_df2 = production_df[production_df['farm_cde'] == '천지인술'] production_df3 = production_df[production_df['farm_cde'] == '토마토명가'] production_df4 = production_df[production_df['farm_cde'] == '이삭줍는 알파고']
Python
복사
데이터 EDA (환경정보-외부환경&내부환경 / 양액정보&토양정보)
# 'measDate' 값이 계속 문자열로 변함 → 테이블이 변경될때마다 datetime으로 변환하기 environment_df['measDate'] = pd.to_datetime(environment_df['measDate']) production_df['measDate'] = pd.to_datetime(production_df['measDate']) growth_df['measDate'] = pd.to_datetime(growth_df['measDate']) environment_mean['measDate'] = pd.to_datetime(environment_mean['measDate'])
Python
복사
# 외부환경과 내부환경에서 필요칼럼 필터링하기 ## sectCode [외부환경(EO)과 내부환경(EI)] ## - FatrCode [외부환경(EO)= 'TE':'외부온도', 'WP':'폭풍신호' , 'RP':'강우신호' , 'SR':'누적광'] [내부환경(EI)= 'IR':'광량', 'TA':'평균온도', 'HI':'습도'] ## 외부환경(EO)과 내부환경(EI)에서 필요칼럼 필터링하기 ## df['farm_cde'].isin(값들의_집합) ## ※ mask 합쳐서 필터링해도 상관없음. environment_mask1= environment_df[environment_df['FatrCode'].isin(['외부온도','폭풍신호','강우신호','누적광'])] environment_mask2= environment_df[environment_df['FatrCode'].isin(['광량','평균온도','습도'])] ## 필요칼럼들 한 테이블로 합치기 environment_1 = pd.concat([environment_mask1, environment_mask2], ignore_index=True) # 환경정보 environment_df에서 외부환경과 내부환경을 필터링한 테이블 environment_1
Python
복사
# ※ environment_1은 분단위 행으로 존재함. ## 작물 품질을 올려주는 최적의 환경요소(FatrCode)인 외부환경(온도,폭풍,강우,누적광) + 내부환경(광량,평균온도,습도)에서 ## environment_df의 날짜,온실,주야 기준으로 senVal(외부환경+내부환경의 분단위 값)값을 시간당 평균값으로 계산함. environment_mean = environment_1.groupby(['measDate','주야','farm_cde','FatrCode'])['senVal'].mean().reset_index() environment_mean
Python
복사
# (머지)작물의 품질을 올려주는 최적의 환경요소가 무엇인가?? # = environment : growth(환경정보와 생육정보) environment_mer1 = pd.merge(environment_mean,growth_df, how='left',on=['measDate','farm_cde']) environment_mer1
Python
복사
# (피벗화) 작물의 품질을 올려주는 최적의 환경요소가 무엇인가?? # = environment : growth(환경정보와 생육정보) env_pivot1= (environment_mer1.pivot_table(index=['measDate','주야','farm_cde'],columns='FatrCode',values='senVal',aggfunc='mean').reset_index()) growth_cols1 = ['measDate','주야','farm_cde','화방높이(cm)','생장길이(cm)','엽수(개)','엽장(cm)','엽폭(cm)','줄기직경(mm)','개화수준(점)','착과수준(점)','수확중 화방수준(점)','열매수(개)'] growth_unique = (environment_mer1[growth_cols1].drop_duplicates(subset=['measDate','주야','farm_cde'])) env_grow_pivot1 = pd.merge(env_pivot1,growth_unique,how='left',on=['measDate','주야','farm_cde'])
Python
복사
# (상관관계 파악) environment : growth(환경정보와 생육정보) env_grow_pivot1.select_dtypes(include='number').corr(method='spearman') import seaborn as sns import matplotlib.pyplot as plt corr = env_grow_pivot1.select_dtypes(include='number').corr(method='spearman') plt.figure(figsize=(8,6)) sns.heatmap( corr, annot=True, cmap='coolwarm', center=0 ) plt.title('Spearman Correlation') plt.show()
Python
복사
# (머지) 작물의 품질을 올려주는 최적의 환경요소가 무엇인가?? # = environment : production(환경정보와 생산정보) environment_mer2 = pd.merge(environment_mean,production_df, how='left',on=['measDate','farm_cde']) environment_mer2
Python
복사
# (피벗화) 작물의 품질을 올려주는 최적의 환경요소가 무엇인가?? = environment : production(환경정보와 생산정보) env_pivot2= (environment_mer2.pivot_table(index=['measDate','주야','farm_cde'],columns=['FatrCode'],values='senVal',aggfunc='mean').reset_index()) product_cols2 = ['measDate','주야','farm_cde','itemGrade','outtrn','상품유무'] product_unique = (environment_mer2[product_cols2].drop_duplicates(subset=['measDate','주야','farm_cde'])) env_product_pivot2 = pd.merge(env_pivot2,product_unique,how='left',on=['measDate','주야','farm_cde']) env_product_pivot2
Python
복사
# environment : production(환경정보와 생산정보) = 상관관계 파악하기 env_product_pivot2.select_dtypes(include='number').corr(method='spearman') import seaborn as sns import matplotlib.pyplot as plt corr = env_product_pivot2.select_dtypes(include='number').corr(method='spearman') plt.figure(figsize=(8,6)) sns.heatmap( corr, annot=True, cmap='coolwarm', center=0 ) plt.title('Spearman Correlation') plt.show()
Python
복사
# 환경정보의 양액정보와 토양정보에서 필요칼럼 필터링하기 ## sectCode [양액정보(NT)과 토양정보(EL)] ## FatrCode [양액정보(NT)= 'EI':'(양액)공급EC', 'EO':'(양액)배액EC' , 'PI':'(양액)공급PH' , 'PO':'(양액)배액PH'] ## FatrCode [토양정보(EL)= 'EL':'토양EC', 'PL':'토양PH'] ## 양액정보(NT)과 토양정보(EL)에서 필요칼럼 필터링하기 ## df['farm_cde'].isin(값들의_집합) ## ※ mask 합쳐서 필터링해도 상관없음. environment_mask3= environment_df[environment_df['FatrCode'].isin(['(양액)공급EC','(양액)배액EC','(양액)공급PH','(양액)배액PH'])] environment_mask4= environment_df[environment_df['FatrCode'].isin(['토양EC','토양PH'])] ## 필요칼럼들 한 테이블로 합치기 environment_2 = pd.concat([environment_mask3, environment_mask4], ignore_index=True) # 환경정보 environment_df에서 양액정보와 토양정보를 필터링한 테이블 environment_2
Python
복사
# ※ environment_2는 분단위 행으로 존재함. ## 품질이 낮은 배꼽썩음과 최소화하는 환경요소(FatrCode)인 양액정보((양액)공급EC,(양액)배액EC,(양액)공급PH,(양액)배액PH) + 토양정보(토양EC,토양PH)에서 ## environment_df의 날짜,온실,주야 기준으로 senVal(양액정보+토양정보의 분단위 값)값을 시간당 평균값으로 계산함. environment_mean2 = environment_2.groupby(['measDate','주야','farm_cde','FatrCode'])['senVal'].mean().reset_index() environment_mean2
Python
복사
# (머지)품질이 낮은 배꼽썩음과 최소화하는 환경요소가 무엇인가?? # = environment : growth(환경정보와 생육정보) environment_mer3 = pd.merge(environment_mean2,growth_df, how='left',on=['measDate','farm_cde']) environment_mer3
Python
복사
# (피벗화)품질이 낮은 배꼽썩음과 최소화하는 환경요소가 무엇인가?? # = environment : growth(환경정보와 생육정보) env_pivot3= (environment_mer3.pivot_table(index=['measDate','주야','farm_cde'],columns='FatrCode',values='senVal',aggfunc='mean').reset_index()) growth_cols3 = ['measDate','주야','farm_cde','화방높이(cm)','생장길이(cm)','엽수(개)','엽장(cm)','엽폭(cm)','줄기직경(mm)','개화수준(점)','착과수준(점)','수확중 화방수준(점)','열매수(개)'] growth_unique3 = (environment_mer3[growth_cols3].drop_duplicates(subset=['measDate','주야','farm_cde'])) env_grow_pivot3 = pd.merge(env_pivot3,growth_unique3,how='left',on=['measDate','주야','farm_cde'])
Python
복사
# (상관관계 파악) environment : growth(환경정보와 생육정보) env_grow_pivot3.select_dtypes(include='number').corr(method='spearman') import seaborn as sns import matplotlib.pyplot as plt corr = env_grow_pivot3.select_dtypes(include='number').corr(method='spearman') plt.figure(figsize=(8,6)) sns.heatmap( corr, annot=True, cmap='coolwarm', center=0 ) plt.title('Spearman Correlation') plt.show()
Python
복사
# (머지)품질이 낮은 배꼽썩음과 최소화하는 환경요소가 무엇인가?? # = environment : production(환경정보와 생산정보) environment_mer4 = pd.merge(environment_mean2,production_df, how='left',on=['measDate','farm_cde']) environment_mer4
Python
복사
# (피벗화)품질이 낮은 배꼽썩음과 최소화하는 환경요소가 무엇인가?? # = environment : production(환경정보와 생산정보) env_pivot4= (environment_mer4.pivot_table(index=['measDate','주야','farm_cde'],columns=['FatrCode'],values='senVal',aggfunc='mean').reset_index()) product_cols4 = ['measDate','주야','farm_cde','itemGrade','outtrn','상품유무'] product_unique4 = (environment_mer4[product_cols4].drop_duplicates(subset=['measDate','주야','farm_cde'])) env_product_pivot4 = pd.merge(env_pivot4,product_unique4,how='left',on=['measDate','주야','farm_cde']) env_product_pivot4
Python
복사
# (상관관계 파악) environment : production(환경정보와 생산정보) env_product_pivot4.select_dtypes(include='number').corr(method='spearman') import seaborn as sns import matplotlib.pyplot as plt corr = env_product_pivot4.select_dtypes(include='number').corr(method='spearman') plt.figure(figsize=(8,6)) sns.heatmap( corr, annot=True, cmap='coolwarm', center=0 ) plt.title('Spearman Correlation') plt.show()
Python
복사