Github에서 sub directory 또는 file 1개만 가져오는 방법

간혹 github을 clone 하려고 할 때, sub directory만 필요한데 생각보다 clone이 가능한 github repository 코드 전체 용량이 심하게 클 경우 clone을 하는게 망설여질 때가 있습니다.

이럴 때 적용할 수 있는 간단한 방법이 있습니다

먼저 해당 sub directory 또는 file을 저장할 local directory를 생성후 해당 directory로 이동합니다

mkdir project
cd project

그러고 나서 아래 github 관련된 명령어를 순차적으로 실행시켜 주시면 됩니다

git init

git config core.sparseCheckout true

git remote add -f origin <clone 가능한 git url>

echo "<갖고 오고 싶은 directory 주소/*>" .git/info/sparse-checkout

git pull origin master

아래 예시를 통해서 좀 더 자세히 보여드리겠습니다

git init

git config core.sparseCheckout true

git remote add -f origin https://github.com/udacity/DSND_Term2.git

echo "lessons/ObjectOrientedProgramming/*"> .git/info/sparse-checkout

git pull origin master

여기서 echo 다음에 가지고올 directory 주소/* 를 하면 sub dir 하위의 파일들을 전부 가지고 옵니다. 만약에 파일 1개만 가지고 오고 싶으시다면 그 파일의 path만 echo 다음에 적어주시면 됩니다.

Numpy Broadcast 브로드캐스트란?

Numpy 다차원 배열에서 shape이 다른 배열끼리의 연산이 가능하게 하는 기능을 브로드캐스트 Broadcast라고 합니다.

예를 들어 2×2 행렬과 scala 2를 곱할 때 scala 2가 2×2로 확장되면서 두 개의 element wise 곱셈이 가능해지는 것입니다. 여기서 element wise란 각각의 개별 원소 by 원소 라고 보시면 됩니다.

a = np.array([[1,2],[3,4]])  
b = np.array([10, 20])
a * b

위에 예시처럼 element wise 곱을 하면 결과는 아래처럼 b라는 1차원 배열이 2차원으로 확장되어서 곱해집니다. 이렇게 자동으로 곱셈이 가능하도록 확장해주는 것이 브로드캐스트의 기능입니다.

array([[10, 40],
       [30, 80]])

브로드캐스트의 경우 같은 shape의 배열끼리 곱하는 것보다 더 적은 메모리를 차지하기 때문에 좀 더 효율적이라고 볼 수 있습니다.

브로드캐스트를 적용이 가능한 경우와 불가능한 경우를 알아보기 위해 numpy 공식 문서를 번역하여 공유드려보도록 하겠습니다.

출처: https://numpy.org/doc/stable/user/basics.broadcasting.html

두 배열에 대해 처리할 때, numpy는 두 배열의 shape을 element-wise 하게 비교합니다. 이때 차원을 살펴보는데, 두 배열이 호환 가능할 때는 다음과 같습니다.

1. 두 축이 똑같거나 또는
2. 둘 중 하나의 축이 1일때 입니다

이 조건이 충족되지 않으면, ValueError: operands could not be broadcast together라는 에러가 발생하면서 배열이 서로 호환되지 않는 shape임을 나타냅니다.

배열은 반드시 같은 차원의 수를 가질 필요는 없습니다. 예를 들어, RGB 값인 256x256x3 배열의 경우, 이미지에 있는 각 컬러를 다른 값에 의해서 확장하고 싶을 때, 그 이미지를 3개의 값으로 이루어진 1차원 배열과 곱할 수 있습니다. 브로드캐스트 규칙에 따라 이러한 배열의 크기에 대해서 다음과 같이 호환가능함을 알 수 있습니다:

Image (3d array): 256 x 256 x 3
Scale (1d array): 3
Result (3d array): 256 x 256 x 3

둘 중 하나의 차원이 1차원인데, 이 1차원이 확장되어서 다른 배열의 차원과 호환이 가능해집니다.

다음 예시를 보면, A와 B 배열 모두 브로드캐스트를 적용할 때 확장이 가능한 길이인 1을 축으로 가지고 있습니다:

A (4d array): 8 x 1 x 6 x 1
B (3d array): 7 x 1 x 5
Result (4d array): 8 x 7 x 6 x 5

브로드캐스트가 가능한 더 많은 예시는 다음과 같습니다:

A      (2d array):  5 x 4
B      (1d array):      1
Result (2d array):  5 x 4

A      (2d array):  5 x 4
B      (1d array):      4
Result (2d array):  5 x 4

A      (3d array):  15 x 3 x 5
B      (3d array):  15 x 1 x 5
Result (3d array):  15 x 3 x 5

A      (3d array):  15 x 3 x 5
B      (2d array):       3 x 5
Result (3d array):  15 x 3 x 5

A      (3d array):  15 x 3 x 5
B      (2d array):       3 x 1
Result (3d array):  15 x 3 x 5

아래 예시는 브로드캐스트가 적용이 안 되는 경우입니다:

A      (1d array):  3
B      (1d array):  4 # 축의 길이가 다릅니다

A      (2d array):      2 x 1
B      (3d array):  8 x 4 x 3 # A의 축 길이 2와 B의 축 길이 4가 맞지 않습니다

실제 브로드캐스트 예시입니다:

>>> x = np.arange(4)
>>> xx = x.reshape(4,1)
>>> y = np.ones(5)
>>> z = np.ones((3,4))

>>> x.shape
(4,)

>>> y.shape
(5,)

>>> x + y
ValueError: operands could not be broadcast together with shapes (4,) (5,)

>>> xx.shape
(4, 1)

>>> y.shape
(5,)

>>> (xx + y).shape
(4, 5)

>>> xx + y
array([[ 1.,  1.,  1.,  1.,  1.],
       [ 2.,  2.,  2.,  2.,  2.],
       [ 3.,  3.,  3.,  3.,  3.],
       [ 4.,  4.,  4.,  4.,  4.]])

>>> x.shape
(4,)

>>> z.shape
(3, 4)

>>> (x + z).shape
(3, 4)

>>> x + z
array([[ 1.,  2.,  3.,  4.],
       [ 1.,  2.,  3.,  4.],
       [ 1.,  2.,  3.,  4.]])

브로드캐스트는 두 배열의 간단한 outer product(외적) 또는 outer operation을 제공합니다.
다음의 예시는 두 개의 1차원 배열의 outer addition operation을 보여줍니다.

>>> a = np.array([0.0, 10.0, 20.0, 30.0]) #a.shape = (4,)
>>> b = np.array([1.0, 2.0, 3.0]) #b.shape = (3,)
>>> a[:, np.newaxis] + b #a[:, np.newaxis].shape = (4,1) & b.shape = (3,)
array([[  1.,   2.,   3.],
       [ 11.,  12.,  13.],
       [ 21.,  22.,  23.],
       [ 31.,  32.,  33.]])

여기서 newaxis index operator는 a에 새로운 축을 삽입하여, 2차원의 4×1 배열을 만들어냅니다. (3,) shape을 가진 b와 4×1 배열을 결합하면 4×3 배열이 됩니다.

SNI란

 

SNI (Server Name Indication) 란 컴퓨터 네트워크 프로토콜인 TLS(Transport Layer Security)의 확장으로, 핸드셰이킹 과정 초기에 클라이언트가 어느 호스트명에 접속하려는지 서버에 알리는 역할을 한다. 이를 이용하면 동일한 IP 주소와 TCP 포트 번호를 가진 서버로 여러 개의 인증서를 사용할 수 있기 때문에 모든 사이트가 같은 인증서를 사용하지 않아도 동일한 아이피로 여러 HTTPS 웹사이트를 운영할 수 있게 된다.

출처: 위키피디아

이렇게 하는 이유는 IPv4 체계 하에서 IP가 부족하기 때문에 동일한 IP 주소에 대해서 여러 개의 인증서를 사용함으로써 여러 웹사이트 운영이 가능하도록 하기 위해서 입니다. 즉 상대적으로 적은 IP 사용이 가능해집니다.

X-Forwarded-For와 X-Forwarded-Proto 란

X-Forwarded-For (XFF) 헤더란 HTTP 프록시 또는 로드 밸런서를 통해서 웹서버에 연결하는 클라이언트의 원래 IP 주소를 식별하기 위한 표준 헤더입니다.

트래픽이 클라이언트와 서버 사이 중간에 프록시 또는 로드밸런서를 통해 전달될 때, 서버 접근 로그는 프록시 또는 로드 밸런서의 IP 주소만 가지고 있습니다. 클라이언트의 오리지널 IP 주소를 보기 위해서는 X-Forwarded-For 리퀘스트 헤더가 사용됩니다. syntax는 다음과 같습니다.

X-Forwarded-For: <client>, <proxy1>, <proxy2>
X-Forwarded-For: 2001:db8:85a3:8d3:1319:8a2e:370:7348

X-Forwarded-For: 203.0.113.195

X-Forwarded-For: 203.0.113.195, 70.41.3.18, 150.172.238.178

X-Forwarded-Proto (XFP) 헤더는 클라이언트가 프록시 또는 로드 밸런서에 연결하는 데 사용되는 HTTP 또는 HTTPS 프로토콜을 식별하기 위한 표준 헤더입니다. 서버 접근 로그는 서버와 로드 밸런서 간에 사용된 프로토콜을 포함하지만, 클라이언트와 로드 밸런서 사이에서 사용된 프로토콜은 포함하지 않습니다. 클라이언트와 로드 밸런서 사이에서 사용된 프로토콜을 식별하기 위해서 X-Forwarded-Proto 리퀘스트 헤더가 사용됩니다.

syntax는 다음과 같습니다.

X-Forwarded-Proto: <protocol>
X-Forwarded-Proto: https

출처:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto

bincount() 란?

bincount()

non negative integer로 구성된 Numpy array에서 각각의 빈도수를 카운트하는데 사용되는 메소드입니다. 0부터 가장 큰 값까지 각각의 발생 빈도수를 체크합니다.

예를 들어, [3,2,2,6,7,4,8,9,9,9] 라는 array가 있습니다. bincount()를 적용한 값을 출력하면, [0 0 2 1 1 0 1 1 1 3] –> 이렇게 출력되는데요 그 이유는,

import numpy as np

given_array = [3,2,2,6,7,4,8,9,9,9]
answer = np.bincount(given_array)
print(answer)
# the printed result is : [0 0 2 1 1 0 1 1 1 3]

0부터 ~ 9까지 각각의 빈도수를 다 체크한 것이기 때문입니다. 즉, 해당 array에 존재하는 3,2,6,7,4,8,9 총 7가지 숫자의 각각의 발생 빈도수만 기록하는 것이 아니라 0부터 9까지의 빈도수가 다 체크되어 있습니다. 그래서 순서대로 하면 0은 0번, 1은 0번, 2는 2번, 3은 1번, 4는 1번, 5는 0번, 6은 1번, 7은 1번, 8은 1번, 9는 3번 이렇게 해서 [0 0 2 1 1 0 1 1 1 3] 이 리턴이 됩니다.