데이터로 읽는
세계 농업의 대서사
Pandas 분석가를 위한 친절한 데이터 사전
1. 데이터 소개: 이 데이터는 무엇이고 왜 중요한가요?
데이터 분석의 여정은 흥미로운 질문에서 시작되지만, 그 질문에 대한 답을 찾기 위해서는 무엇보다도 손에 쥔 데이터를 깊이 이해하는 과정이 필수적입니다. 이 보고서는 유엔식량농업기구(Food and Agriculture Organization of the United Nations, 이하 FAO)에서 제공하는 방대하고 유서 깊은 FAO.csv 데이터셋의 구조와 의미를 상세히 탐색하는, 여러분의 데이터 분석 여정을 위한 친절한 나침반이 되고자 합니다.
이 데이터셋의 가장 큰 가치는 그 출처의 신뢰성과 방대한 범위에 있습니다. 세계 식량 및 농업 분야에서 가장 권위 있는 기관인 FAO가 수집하고 관리하는 FAOSTAT의 일부이며, 구체적으로는 각국의 식량 공급 패턴을 종합적으로 보여주는 **'식량수급표(Food Balance Sheets)'**에 기반을 두고 있습니다. 식량수급표는 단순한 '생산량'이 아니라, 특정 기간 동안 한 국가에서 생산된 총 식량에 수입량을 더하고 재고 변동을 조정한 **'공급 가능량(Supply available)'**을 보여준다는 점에서 더욱 깊은 의미를 가집니다.
데이터는 1961년부터 2013년까지, 약 53년간에 걸쳐 전 세계 199개 국가 및 지역의 농축수산물 공급량을 기록하고 있습니다. 이 긴 시간적 범위는 제2차 세계대전 이후 본격화된 농업 기술의 발전, 녹색 혁명, 그리고 세계화가 각국의 식량 시스템에 미친 영향을 장기적인 관점에서 추적할 수 있게 해줍니다. 이 데이터는 미래의 식량 안보(Food Security) 전략을 수립하고, 식량 시스템이 환경에 미치는 영향을 연구하는 데 핵심적인 기초 자료를 제공합니다.
2. 데이터 분석을 위한 핵심 개념
2.1. 가장 중요한 개념: 식량(Food) vs. 사료(Feed)
이 데이터셋을 관통하는 가장 핵심적인 분류 기준은 바로 Element 컬럼에 담긴 '식량(Food)'과 '사료(Feed)'의 구분입니다. 이 두 가지 개념은 한 국가의 농업 자원이 어떻게 배분되고 있는지를 보여주는 근본적인 지표입니다.
Food (식량, Element Code 5142): "해당 기간 동안 인간의 식량으로 사용 가능한 품목의 총량"을 의미합니다.
Feed (사료, Element Code 5521): "해당 기간 동안 가축 및 가금류에게 먹이로 제공 가능한 품목의 양"을 의미합니다.
이 구분은 각국의 농업 시스템과 식문화의 특징을 파악하는 데 결정적인 단서를 제공합니다. 예를 들어, **'사료-식량 비율(Feed-to-Food Ratio)'**이라는 강력한 파생 지표를 만들어, 특정 국가의 육류 소비 수준이나 산업화된 축산업의 규모를 가늠해볼 수 있습니다.
2.2. 데이터 구조: 'Wide' 포맷과 'Tidy' 포맷 이해하기
FAO.csv 파일은 1961년부터 2013년까지의 연간 데이터가 Y1961, Y1962,..., Y2013과 같이 총 53개의 개별 컬럼으로 존재하는 **와이드 포맷(Wide Format)**입니다. 이 형식은 사람이 눈으로 데이터를 훑어보기에는 편리할 수 있지만, 프로그래밍을 통한 데이터 분석에는 여러 제약을 가집니다.
이러한 문제를 해결하기 위한 표준적인 접근 방식이 바로 데이터를 **'롱 포맷(Long Format)'** 또는 **'타이디 데이터(Tidy Data)'** 형태로 변환하는 것입니다. 53개의 연도 컬럼을 '녹여서(melt)' 'Year'와 'Value'라는 단 두 개의 컬럼으로 만들면, 연도별 필터링, 그룹별 집계, 시계열 시각화 등 대부분의 분석 작업을 훨씬 간결하고 효율적인 코드로 수행할 수 있습니다.
3. 데이터 사전: 컬럼별 상세 탐색 및 분석 팁
데이터의 잠재력을 최대한 활용하기 위해서는 각 컬럼이 무엇을 의미하는지, 어떤 종류의 값을 가지고 있는지, 그리고 분석 과정에서 어떻게 다루어야 하는지를 명확하게 알아야 합니다.
3.1. 마스터 데이터 사전 테이블
| 컬럼명 | 자료형(Pandas) | 설명 |
|---|---|---|
Area Abbreviation | object (string) | 국가/지역의 3자리 ISO 표준 약어 코드. (예: AFG, KOR, USA) |
Area Code | int64 | FAO에서 부여한 국가/지역의 고유 숫자 코드. 다른 FAO 데이터셋과 조인할 때 유용. |
Area | object (string) | 국가 또는 지역의 전체 이름. |
Item Code | int64 | 농축수산물 품목의 고유 숫자 코드. |
Item | object (string) | 농축수산물 품목의 이름. (예: Wheat and products, Maize) |
Element Code | int64 | 품목의 사용 목적(요소)에 대한 고유 숫자 코드. (예: 5142, 5521) |
Element | object (string) | 품목의 사용 목적. 'Food'(식량) 또는 'Feed'(사료) 중 하나. |
Unit | object (string) | 연도별 데이터의 측정 단위. 데이터셋 전체에서 '1000 tonnes'로 일관됨. |
latitude, longitude | float64 | 해당 지역의 지리적 위도와 경도. 지도 시각화에 사용. |
Y1961...Y2013 | float64 | 해당 연도의 생산/공급량. |
3.2. 지리적 식별자: '어디서' 생산되었는가?
Area, Area Code, Area Abbreviation, latitude, longitude 컬럼은 데이터의 지리적 위치를 나타냅니다. 다른 데이터(예: 인구, 기후)와 병합(merge)할 때, 국가 이름(Area)은 표기법 차이로 오류를 유발할 수 있습니다. 따라서 기계적 처리에는 변하지 않는 고유 숫자 코드인 **Area Code를 조인 키(key)로 사용하는 것이 가장 안정적이고 정확한 방법**입니다.
3.3. 품목 식별자: '무엇을' 생산했는가?
가장 치명적인 함정: 품목의 계층 구조와 이중 계산(Double-Counting)
Item 컬럼에는 'Bovine Meat', 'Poultry Meat'와 같은 개별 육류 항목과 이들을 모두 합산한 'Meat'라는 상위 집계 항목이 함께 들어있습니다. 만약 "총 육류 생산량"을 계산하기 위해 개별 품목 값을 모두 더한 후, 'Meat'의 값까지 더한다면 이는 명백한 **이중 계산**으로, 실제보다 훨씬 부풀려진 잘못된 결과를 도출하게 됩니다. 이는 분석의 신뢰도를 심각하게 훼손할 수 있으므로, 분석 목적에 따라 올바른 수준의 품목을 선택하는 것이 매우 중요합니다.
4. 데이터 변환: 분석을 위한 필수 전처리 과정
가장 중요한 실용 팁: melt()로 데이터 구조 변경하기
이 데이터셋으로 의미 있는 시계열 분석을 시작하려면, 가장 먼저 53개의 연도 컬럼을 두 개의 컬럼('Year', 'Value')으로 변환하는 'Tidy' 데이터 형태로 만들어야 합니다. 이 과정은 Pandas의 melt() 함수를 통해 손쉽게 수행할 수 있으며, 모든 후속 분석을 훨씬 직관적이고 간결하게 만듭니다.
Python Code: Wide to Long Transformation
# 1. 분석의 기준이 될 ID 컬럼들을 리스트로 정의합니다.
# 이 컬럼들은 변환 과정에서 그대로 유지됩니다.
id_vars = [
'Area', 'Area Code', 'Area Abbreviation', 'Item', 'Item Code',
'Element', 'Element Code', 'Unit', 'latitude', 'longitude'
]
# 2. 값으로 변환할 연도 컬럼들을 리스트로 정의합니다.
# 'Y'로 시작하는 모든 컬럼을 동적으로 선택합니다.
value_vars = [col for col in df.columns if col.startswith('Y')]
# 3. pd.melt 함수를 사용하여 데이터를 'long' 포맷(Tidy Data)으로 변환합니다.
df_long = pd.melt(
df,
id_vars=id_vars,
value_vars=value_vars,
var_name='Year', # 새로 생성될 연도 컬럼의 이름
value_name='Value' # 새로 생성될 값 컬럼의 이름
)
# 4. 'Year' 컬럼에서 'Y' 문자를 제거하고, 숫자형(int)으로 변환합니다.
df_long['Year'] = df_long['Year'].str.replace('Y', '').astype(int)
# 5. 결측치를 확인하고 필요한 경우 처리합니다.
df_long.dropna(subset=['Value'], inplace=True)
# 변환된 데이터프레임의 구조를 확인합니다.
print("데이터 변환 후 샘플:")
print(df_long.head())
5. 종합 실습: 사전 지식을 분석으로 연결하기
5.1. 분석 질문 설정
"주요 농업 생산국인 미국과 중국에서, 1961년부터 2013년까지 옥수수(Maize and products) 공급량은 인간의 식량(Food)과 동물의 사료(Feed) 사이에서 어떻게 변화해왔는가? 이 추세는 두 국가의 농업 시스템에 대해 무엇을 말해주는가?"
5.2. Pandas를 이용한 단계별 분석
위에서 설정한 질문에 답하기 위해 Python의 Pandas와 Matplotlib, Seaborn 라이브러리를 사용하여 단계별로 분석을 진행하겠습니다. 아래 코드는 각 단계에 대한 상세한 주석을 포함하고 있어, 코드의 흐름을 쉽게 따라갈 수 있습니다.
# Python Code: US vs China Maize Analysis
# --- 1단계: 라이브러리 임포트 및 데이터 로드 ---
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
try:
# 'ISO-8859-1'(latin1) 인코딩은 특수 문자를 처리하기 위해 필요할 수 있습니다.
df = pd.read_csv('FAO.csv', encoding='ISO-8859-1')
except FileNotFoundError:
print("FAO.csv 파일을 찾을 수 없습니다.")
# --- 2단계: 데이터 변환 (Wide to Long) ---
id_vars = ['Area', 'Item', 'Element']
value_vars = [col for col in df.columns if col.startswith('Y')]
df_long = pd.melt(df, id_vars=id_vars, value_vars=value_vars, var_name='Year', value_name='Value')
df_long['Year'] = df_long['Year'].str.replace('Y', '').astype(int)
df_long.dropna(subset=['Value'], inplace=True)
# --- 3단계: 데이터 필터링 ---
countries_of_interest = ['United States of America', 'China, mainland']
item_of_interest = 'Maize and products'
analysis_df = df_long.query(
"Area in @countries_of_interest and Item == @item_of_interest"
)
# --- 4단계: 데이터 시각화 ---
plt.figure(figsize=(16, 9))
sns.set_theme(style="whitegrid")
plot = sns.lineplot(
data=analysis_df, x='Year', y='Value',
hue='Area', # 국가별로 선의 색상을 다르게 표시
style='Element', # Food/Feed별로 선의 스타일(실선/점선)을 다르게 표시
linewidth=2.5, marker='o', markersize=5
)
plot.set_title('미국과 중국의 옥수수 공급량 변화 (1961-2013)', fontsize=20, pad=20)
plot.set_ylabel('공급량 (단위: 천 톤)', fontsize=14)
plot.set_xlabel('연도', fontsize=14)
plt.legend(title='범례', title_fontsize='13')
plt.show()
5.3. 시각화 및 결과 해석
미국 (United States of America)
그래프에서 미국은 1961년부터 사료용(Feed) 옥수수 공급량이 식량용(Food)을 압도하는 모습을 보입니다. 이 격차는 시간이 지남에 따라 더욱 커져, 2013년에는 사료용 공급량이 식량용의 수십 배에 달합니다. 이는 미국이 거대한 규모의 산업적 축산업을 기반으로 한 국가이며, 옥수수를 인간이 직접 소비하기보다는 주로 가축을 기르는 데 사용하는 농업 시스템을 가지고 있음을 명백히 보여줍니다.
중국 (China, mainland)
중국의 경우, 1980년대까지는 식량용 옥수수 공급량이 사료용보다 많거나 비슷한 수준을 유지합니다. 하지만 1990년대 이후, 특히 2000년대에 들어서면서 사료용 옥수수 공급량이 폭발적으로 증가하여 식량용을 크게 앞지르기 시작합니다. 이 극적인 변화는 중국의 급속한 경제 성장과 맞물려 있으며, 국민 소득 증가에 따른 육류 소비량 증가와 그에 따른 축산업의 대규모 확장을 시사합니다.
6. 마무리하며: 이제 여러분의 분석 여정이 시작됩니다
지금까지 우리는 FAO의 방대한 데이터셋을 탐험하는 여정을 함께했습니다. 데이터의 출처와 중요성부터 시작하여, 각 컬럼의 상세한 의미와 분석 시 유의해야 할 함정들, 그리고 실제 Pandas 코드를 이용한 분석 실습까지, 이 데이터셋을 다루는 데 필요한 핵심적인 지식들을 모두 살펴보았습니다.
핵심 요약
pd.melt()를 사용하여 '롱 포맷'으로 변환하는 것이 시계열 분석의 가장 중요한 첫 단계입니다. 더 나아간 탐험을 위한 제언
여기서 멈추지 말고, 자신만의 호기심을 따라 새로운 질문을 던져보세요.
- 사료-식량 비율(Feed-to-Food Ratio) 계산: 국가별, 대륙별 축산업 의존도를 직접 비교하고, 특정 국가가 경제 발전에 따라 이 비율이 어떻게 변화했는지 추적해보세요.
- 지리 공간 분석 심화:
plotly나folium라이브러리를 사용하여 특정 작물의 연도별 생산량 변화를 인터랙티브한 세계 지도로 만들어보세요. - 1인당 공급량 분석: 다른 데이터셋에서 인구 데이터를 가져와 결합하면, 국가 간의 실질적인 소비 패턴 차이를 더욱 명확하게 비교할 수 있습니다.
즐거운 분석 여정이 되시길 바랍니다!