python을 사용하여 디렉토리 안의 특정 확장자 또는 모든 파일을 찾을 수 있습니다.

--> import glob

을 통해 쉽게 접근할 수 있습니다.


1. 폴더 안의 모든 디렉토리 찾기

all_dir = glob.glob('./my_dir/*')

위와 같이 *을 사용하면 확장자 상관없이 모든 파일을 가져오겠다는 의미입니다.


2. 폴더 안의 폴더 안의 폴더 안의 파일 찾기

폴더 안에 또 디렉토리가 있는 경우가 있습니다. 

그럴때는 glob 함수에서 제공하는 파라미터인 recursive를 활성화시켜주면 됩니다.

# 디렉토리 안의 모든 파일을 찾고 싶은 경우(sub directory도 포함)
all_dir = glob.glob('./my_dir/*', recursive = True)

3. 특정 확장자만 찾기

이 또한, recursive를 활성화시켜주면 내부 폴더안의 폴더까지 뒤져서 전부 찾아줍니다.

all_dir = glob.glob('./my_dir/*.jpg')

all_dir = glob.glob('./my_dir/*.jpg', recursive = True)

 


4. glob을 이용하여 파일 생성일, 사이즈 등을 기준으로 정렬하고 싶은 경우

편리하게 쓸 수 있는 order는 여러가지가 있지만 대표적으로 다음과 같습니다.

  • os.path.getctime # 파일 생성일
  • os.path.getmtime # 파일 최근 수정일
  • os.path.getatime # 파일 접근일
  • os.path.getsize # 파일 사이즈
sorted_all_dir = sorted(glob.glob('./my_dir/*'), key = order)

 

밑에 나오는 plot들은 IEEE-fraud detection competition과 그 커널을 참조합니다. 

  • sns -> seaborn
  • pd -> pandas
  • plt -> matplotlib.pyplot
  • go -> plotly.graph_objs

subplot간 간격 조정 : plt.subplots_adjust(hspace = num, top = num)

x label 숫자 회전 : plot객체.set_xticklabels(g.get_xticklabels(), rotation = 45)


sns.distplot()


plt.scatter()


sns.countplot()


sns.countplot() + sns.pointplot()


sns.boxenplot()


sns.distplot() + sns.displot()


go.scatter()

https://www.kaggle.com/c/ieee-fraud-detection/data
 

IEEE-CIS Fraud Detection

Can you detect fraud from customer transactions?

www.kaggle.com

주로 이미지 관련한 competition이 주로 개최되다가 오랜만에 숫자값을 예측하는 대회가 열렸네요.

고객의 거래 데이터의 이상징후를 감지해보는 대회입니다.

대회의 데이터를 받아보면 상당히 많은 데이터로 메모리를 많이 잡아먹습니다. 실제로 불러오는데에도 시간이 많이 소비됩니다.

여러 커널에서는 메모리를 줄이기 위한 여러 코드를 사용하고 있는데요. 이 글에서는 다음 커널을 참조하였습니다.

https://www.kaggle.com/kabure/extensive-eda-and-modeling-xgb-hyperopt
 

Extensive EDA and Modeling XGB Hyperopt

Using data from IEEE-CIS Fraud Detection

www.kaggle.com


## Function to reduce the DF size
def reduce_mem_usage(df, verbose=True):
    numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
    start_mem = df.memory_usage().sum() / 1024**2    
    for col in df.columns:
        col_type = df[col].dtypes
        if col_type in numerics:
            c_min = df[col].min()
            c_max = df[col].max()
            if str(col_type)[:3] == 'int':
                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
                    df[col] = df[col].astype(np.int8)
                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
                    df[col] = df[col].astype(np.int16)
                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
                    df[col] = df[col].astype(np.int32)
                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
                    df[col] = df[col].astype(np.int64)  
            else:
                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
                    df[col] = df[col].astype(np.float16)
                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
                    df[col] = df[col].astype(np.float32)
                else:
                    df[col] = df[col].astype(np.float64)    
    end_mem = df.memory_usage().sum() / 1024**2
    if verbose: print('Mem. usage decreased to {:5.2f} Mb ({:.1f}% reduction)'.format(end_mem, 100 * (start_mem - end_mem) / start_mem))
    return df

실제로 데이터의 type들을 출력해보면 대부분 int64, float64로 이루어져있습니다. 

실제 데이터는 int64로 type이 잡혀있지만 실제로 데이터의 범위는 int16범위에만 속한다면?

이에 맞게 줄여줘야 메모리 사용을 줄일 수 있지 않을까요??

위 커널(뿐만 아니라 다른 커널까지)은 이 외에 데이터를 다루는데에 여러 시각화 기법과 Modeling 기법을 설명하고 있습니다.

이 커널만 분석하여도 꽤나 많은 정보를 얻으실 것 같네요.


<object> -> <bndbox> -> 4개의 coord가져오기

(데이터는 사진과 다릅니다)

import xml.etree.ElementTree as elemTree
tree = elemTree.parse(annotation_list[0])
object_a = tree.find('object')
print(object_a.find('bndbox')[0], object_a.find('bndbox')[0].text)
print(object_a.find('bndbox')[1], object_a.find('bndbox')[1].text)
print(object_a.find('bndbox')[2], object_a.find('bndbox')[2].text)
print(object_a.find('bndbox')[3], object_a.find('bndbox')[3].text)

print 결과 이미지

이 글은 파이썬에서 * 표현이 어떤 용도로 사용하는지에 대해 다룹니다.


1. 곱셈과 거듭제곱

- 굳이 코드를 붙이지 않아도 다들 아실거라고 생각합니다.

  • 1 * 2 = 2
  • 2 ** 2 = 4

2. 리스트 확장

* 를 사용하여 리스트를 간단히 확장할 수 있습니다.


3. 가변인자

가변인자란, 이름 그대로 길이가 변할 수 있는 argument를 말합니다. 

임의의 함수에 인자로 몇개의 데이터가 들어올지 모르게 되는 경우에 사용하면 편리합니다. 

이때 여러 api나 잘 짜여진 코드를 구경하다보면 함수에 *args**kwargs라고 되있는 표현들을 많이 볼 수 있습니다.

이게 바로 가변인자를 사용하겠다는 의미입니다. 한개와 두개의 차이는 positional과 keyward 인자의 차이입니다. 

이름만 들어서는 낯설 수 있지만, 사실 이미 사용하고 있을지도 모릅니다. 각각은 아래와 같습니다.

def function(a, b = None):
...

여기서 a는 positional arguments, b는 keyword arguments라고 칭합니다. 모두 아시다시피 a는 값이 없는 경우 error가 뜨게 되며, b는 default값으로 None값을 주게 되죠.

아래 예제처럼 args는 tuple 또는 list, kwargs는 dict에 저장되어 출력되는 것을 볼 수 있으며, 동시에 사용할 수도 있습니다. 

def args_function(*args):
    print(args)

def kwargs_function(**kwargs):
    print(kwargs)
    
args_function('a', 'b') # ('a', 'b')
kwargs_function(a = 100, b = 200) # {'a':100, 'b':200}

4. Unpacking

알고리즘을 짜다보면 결과부분을 출력할 때, for-lopp를 이용하여 list를 순회하며 출력하는 경우가 있습니다.

# list unpacking
test = [1, 2, 3, 4]
print(*test) # 1 2 3 4

# tuple unpacking
test = (5, 6, 7, 8)
print(*test) # 5 6 7 8

이렇게 사용하면 코드 길이도 줄고 편리하죠?

다음은 각 변수 중 하나에 가변적으로 할당하고 싶은 경우입니다. 

다음과 같이 사용할 수도 있습니다.

test = [1, 2, 3, 4, 5]

*a, b = test
print(a, b) # [1, 2, 3, 4], 5

a, *b, c = test
print(a, b, c) # 1, [2, 3, 4], 5