1T_os, shutil 모듈을 이용한 파일,폴더 관리하기 (1) - 폴더 생성 및 제거

  • 영화별 매출 - Revenue per Film 이거 어려워. 이거 뽑아 보겠음
  • 데이터를 저장하고 관리하기 위해서 os, shutil - python 내장 라이브러리를 쓸 것임
  • 각 국가별 이름으로 (korea.csv / japan.csv...) 저장하는 거를 할 것임
  • 1T에는 os module, shutil module로 파일, 폴더, 압축파일(데이터) 등을 저장하고 읽고 쓰고 관리할 것임. 파이썬으로만

In [1]:
import os
#os 모듈을 통해서
#운영체제 레벨(서버는 ex.우분투)에서 다루는 파일 폴더 생성하고 삭제하기가 가능
#기존에는 ("../../~~") 이런 식으로 경로를 직접 입력 했으나

In [2]:
os.listdir()
#현재 폴더 안에 있는 파일들을 리스트로 뽑는 것


Out[2]:
['.ipynb_checkpoints',
 '14일차_1T_os, shutil 모듈을 이용한 파일,폴더 관리하기 (1) - 폴더 생성 및 제거.ipynb']

In [3]:
os.listdir("../")


Out[3]:
['.ipynb_checkpoints',
 '01일차.수_입문',
 '02일차.목_함수',
 '03일차.금_전처리,클래스',
 '04일차.월_데코레이터, 클래스상속',
 '05일차.화_디버깅,예외,예외처리,우분투,숙제_하노이의탑',
 '06일차.수_클래스, 데코',
 '07일차.목_크롤링, 정규표현식',
 '08일차.금_정규표현식, class, 크롤링, 숙제',
 '09일차.목_크롤링',
 '10일차.금_크롤링과 API이용',
 '11일차.목_Pandas',
 '12일차.금_Pandas의 고급기능_DB',
 '13일차.목_pandas + SQL',
 '14일차.금_pandas + SQL_2',
 '15일차.목_SQL실습',
 '16일차.금_nosql',
 '17일차.목_AWS, CI',
 '18일차.금_Python 버전관리(AWS), 코호트, github']

In [4]:
for csv_file in os.listdir("../"):
    pass

ipynb 라는 확장자로 끝나는 파일들만 가지고 오려면


In [6]:
[
    file_name
    for file_name
    in os.listdir("../01일차.수_입문/")
    if file_name.endswith(".ipynb")   # csv 파일 가져오기, 엑셀 파일 가져오기로 사용
]


Out[6]:
['1일차 복습.ipynb']

파일에 대한 경로를 생성할 때

  • 현재 폴더 안에 있는, "data"라는 폴더의 "data.csv"의 경로
  • "data/data.csv"
  • "./data/data.csv" ( String 으로 입력할 때 이렇게 직접 ) // 무조건 이 방법으로
  • "/home/python/notebooks/dobestan/dss/....../data/data.csv" - 절대 경로 // 잘 안 씀

In [8]:
os.path.join("data", "data.csv")


Out[8]:
'data\\data.csv'

In [9]:
os.curdir


Out[9]:
'.'

In [10]:
os.path.join(os.curdir, "data", "data.csv")
# 이렇게 하면 경로를 알려줘. 앞으로 만들 때는 무조건 이렇게 만들겠다. 
# os.path.join(os.curdir, "data", file_name)


Out[10]:
'.\\data\\data.csv'
  • os.curdir #current directory
  • os.path.join(...)
  • os.listdir(...)

In [11]:
os.makedirs("data")   #잠재적인 문제가 있다.

In [12]:
os.listdir()   #폴더 만들기는 쉽게 됩니다.


Out[12]:
['.ipynb_checkpoints',
 '14일차_1T_os, shutil 모듈을 이용한 파일,폴더 관리하기 (1) - 폴더 생성 및 제거.ipynb',
 'data']

In [13]:
os.rmdir("data")   #잠재적인 문제가 있다.

In [14]:
os.listdir()


Out[14]:
['.ipynb_checkpoints',
 '14일차_1T_os, shutil 모듈을 이용한 파일,폴더 관리하기 (1) - 폴더 생성 및 제거.ipynb']
  • 폴더를 만들 때, os.listdir()로 특정 폴더가 있는지 확인한 후에, 만약 있으면 삭제하고 새로운 폴더를 생성한다.
  • 폴더를 지울 때, 만약에

In [15]:
os.makedirs("data")  # DATA라는 폴더 안에 간단한 텍스트 파일 만들기

In [16]:
os.listdir(os.path.join(os.curdir,"data"))


Out[16]:
['.ipynb_checkpoints', 'hello.txt']

In [18]:
os.rmdir("data")
# 폴더 안에 파일이 있으면 삭제가 안 된다
# os.listdir()로 찾아본 다음에 폴더면 또 들어가서 다시 재귀적으로 찾아보고,
# 파일이면 삭제하고 상위폴더로 올라와서 그리고 rmdir() ...


---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
<ipython-input-18-0f4cf406ddb8> in <module>()
----> 1 os.rmdir("data")

OSError: [WinError 145] 디렉터리가 비어 있지 않습니다: 'data'
  • 설정 파일 같은 것을 수정하거나 삭제할 때
  • 만약에 .bash_profile => .bash_profile.tmp / ... (복사해주고 작업을 한다.)
  • 복구는 안 된다.
  • 위와 같은 과정의 flow는 어려워
  • 그래서 shutil이라는 파이썬 내장 모듈을 사용할 것임

In [19]:
import shutil
  • os - low-level (저수준)으로 파일/폴더/운영체제를 관리했다면
  • shutil - high-level (고수준) 으로 파일/폴더를 관리

In [20]:
os.listdir(os.path.join(os.curdir, "data"))


Out[20]:
['.ipynb_checkpoints', 'hello.txt']

In [21]:
shutil.rmtree(os.path.join(os.curdir, "data"))

In [22]:
os.listdir(os.path.join(os.curdir, "data"))


---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
<ipython-input-22-def7ddfe6a87> in <module>()
----> 1 os.listdir(os.path.join(os.curdir, "data"))

FileNotFoundError: [WinError 3] 지정된 경로를 찾을 수 없습니다: '.\\data'

In [23]:
os.makedirs(os.path.join(os.curdir, "data"))

In [25]:
shutil.rmtree(os.path.join(os.curdir, "data"))

1. 국가명.csv 파일로 만들기 => world.tar.gz (world.zip) 압축하기

2. 대륙명/국가명.csv 파일로 만들기 => 대륙명.tar.gz 압축하기

ex) Angola.csv -- 도시 정보 csv파일이 국가별로 있어야 합니다. ("data/world/__.csv" 이 200개 정도 있어야 함)


In [28]:
os.makedirs(os.path.join(os.curdir, "data"))
os.makedirs(os.path.join(os.curdir, "data", "world"))
# 만약 "data", "world"라는 폴더가 있으면, 삭제하는 기능 ...


---------------------------------------------------------------------------
FileExistsError                           Traceback (most recent call last)
<ipython-input-28-b6823f8d41d0> in <module>()
----> 1 os.makedirs(os.path.join(os.curdir, "data"))
      2 os.makedirs(os.path.join(os.curdir, "data", "world"))

C:\Anaconda3\lib\os.py in makedirs(name, mode, exist_ok)
    239             return
    240     try:
--> 241         mkdir(name, mode)
    242     except OSError:
    243         # Cannot rely on checking for EEXIST, since the operating system

FileExistsError: [WinError 183] 파일이 이미 있으므로 만들 수 없습니다: '.\\data'
  • df.tocsv(os.path.join(__, , .csv))
  • df.to_csv("./data/world/Angola.csv")

In [29]:
# 폴더의 유무를 확인하고, 있으면 삭제한다.
if "data" in os.listdir():
    print("./data/ 폴더를 삭제합니다.")
    shutil.rmtree(os.path.join(os.curdir, "data"))

# "data"라는 폴더를 생성하고, 그 안에 "world"라는 폴더를 생성한다.
print("./data/ 폴더를 생성합니다.")
os.makedirs(os.path.join(os.curdir, "data"))
os.makedirs(os.path.join(os.curdir, "data", "world"))


./data/ 폴더를 삭제합니다.
./data/ 폴더를 생성합니다.

In [30]:
import pymysql

db = pymysql.connect(
    "db.fastcamp.us",
    "root",
    "dkstncks",
    "world",
    charset='utf8'
)

country_df = pd.read_sql("SELECT * FROM Country;", db)
city_df = pd.read_sql("SELECT * FROM City;", db)
#Country.Code를 바탕으로, City.CountryCode와 매칭해서 찾아야 함
#Country.Name은 반드시 가지고 와야지 파일명으로 저장이 가능

In [31]:
city_groups = city_df.groupby("CountryCode")

In [35]:
for index, row in country_df.iterrows():
    country_code = row["Code"]
    country_name = row["Name"]
    
    city_df = city_groups.get_group(country_code)
    city_df.to_csv(os.path.join("data", "world", "{country_name},csv".format(country_name=country_name)))


---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-35-dd105b3e53fa> in <module>()
      3     country_name = row["Name"]
      4 
----> 5     city_df = city_groups.get_group(country_code)
      6     city_df.to_csv(os.path.join("data", "world", "{country_name},csv".format(country_name=country_name)))

C:\Anaconda3\lib\site-packages\pandas\core\groupby.py in get_group(self, name, obj)
    585         inds = self._get_index(name)
    586         if not len(inds):
--> 587             raise KeyError(name)
    588 
    589         return obj.take(inds, axis=self.axis, convert=False)

KeyError: 'ATA'

In [37]:
#"ATA"라는 애가 없다고 나오니까 테스트
SQL_QUERY = """
    SELECT *
    FROM City
    WHERE CountryCode = "ATA"
    ;
"""
pd.read_sql(SQL_QUERY, db)


Out[37]:
ID Name CountryCode District Population

In [38]:
city_groups.get_group("ATA")


---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-38-e88e97dffee4> in <module>()
----> 1 city_groups.get_group("ATA")

C:\Anaconda3\lib\site-packages\pandas\core\groupby.py in get_group(self, name, obj)
    585         inds = self._get_index(name)
    586         if not len(inds):
--> 587             raise KeyError(name)
    588 
    589         return obj.take(inds, axis=self.axis, convert=False)

KeyError: 'ATA'

In [39]:
"ATA" in city_groups["CountryCode"].unique()


Out[39]:
False

In [40]:
#없는게 증명 됐으니 if문 첨가
for index, row in country_df.iterrows():
    country_code = row["Code"]
    country_name = row["Name"]
    
    if country_code in city_df["CountryCode"].unique():
        one_city_df = city_groups.get_group(country_code)
        one_city_df.to_csv(os.path.join(os.curdir, "data", "world", "{country_name}.csv".format(country_name=country_name)))