<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>hi_rice.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Sun, 25 May 2025 16:58:27 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>hi_rice.log</title>
            <url>https://velog.velcdn.com/images/hi_rice/profile/68009557-c215-4490-8f60-a7b1c7163cde/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. hi_rice.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/hi_rice" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[서초 AI 칼리지] - (4)]]></title>
            <link>https://velog.io/@hi_rice/%EC%84%9C%EC%B4%88-AI-%EC%B9%BC%EB%A6%AC%EC%A7%80-4</link>
            <guid>https://velog.io/@hi_rice/%EC%84%9C%EC%B4%88-AI-%EC%B9%BC%EB%A6%AC%EC%A7%80-4</guid>
            <pubDate>Sun, 25 May 2025 16:58:27 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hi_rice/post/68613234-c78f-4696-a4e3-e2401733df17/image.png" alt=""></p>
<h2 id="m04---조건문">M04 - 조건문</h2>
<h3 id="조건문---if문">조건문 - if문</h3>
<p>if문에 있는 조건의 진리값에 따라 코드의 실행여부가 결정된다.
참이면 if문 밑에 있는 코드가 실행되고, 거짓이면 코드를 실행하지 않고 탈출한다.
여러 조건을 확인해야 될 수도 있다.
elif(else if의 약자)문을 쓰면 된다.</p>
<p>조건문의 조건이 참이면 아래의 코드가 실행된 후 모든 연결된 조건문에서 탈출한다.</p>
<ul>
<li>elif문에 있는 조건 _b를 확인하지 않고, elif 밑에 있는 코드 _b도 실행되지 않는다.</li>
</ul>
<p>거짓이면 연결된 다음 조건문으로 간다.
들여쓰기가 중요하다.</p>
<pre><code>if 조건_a:
    # 코드_a
elif 조건_b:
    # 코드_b</code></pre><p>elif문은 연결된 조건문 안에 여러번 사용할 수 있다.
연결된 조건문들에서 elif 이후 if를 쓰면 안 된다.
정확히는 사용 할 수는 있지만 연결이 안 된다.</p>
<pre><code>if 조건_a:
    # 코드_a
elif 조건_b:
    # 코드_b
elif 조건_c:
    # 코드_c
elif 조건_d:
    # 코드_d</code></pre><p>모든 조건이 거짓일 때 실행하고 싶은 코드가 있을 수도 있다.
else문을 쓰면 된다.</p>
<ul>
<li>else문은 조건이 없다.</li>
</ul>
<p>else문 이후 다른 조건을 연결할 수 없다.
(else문이 조건문의 끝이다.)</p>
<pre><code>if 조건_a:
    # 코드_a
elif 조건_b:
    # 코드_b
elif 조건_c:
    # 코드_c
elif 조건_d:
    # 코드_d
else:
    # 코드_e</code></pre><h3 id="조건문---if문-정리">조건문 - if문 정리</h3>
<p>조건문에 있는 조건의 진리값에 따라 다른 코드를 실행
if로 무조건 시작한다.
elif는 0개에서 여러개까지 가능
else는 최대 1번까지 가능</p>
<h3 id="조건문---삼항-연산자ternary-operator">조건문 - 삼항 연산자(ternary operator)</h3>
<p>한 줄로 조건문을 표현할 수 있다.
trueValue if condition else flaseValue</p>
<pre><code>코드_a id 조건_a else 코드_b if 조건_b else 코드_c</code></pre><p>코드_a - trueValue
조건_a - condition
코드_b if 조건_b else 코드_c - falseValue</p>
<h3 id="조건문과-반복문---break">조건문과 반복문 - break</h3>
<p>반복문 안에서 사용할 수 있는 키워드가 있다.
break 예약어는 실행되자마자 반복문에서 바로 탈출한다.</p>
<h3 id="조건문과-반복문---continue">조건문과 반복문 - continue</h3>
<p>continue 키워드는 실행되자마자 남은 코드를 실행하지 않고, 실행 순서가 다시 반복문 첫줄로 돌아간다.
for문은 객체를 새로 받고, while문은 다시 조건을 확인한다.</p>
<p>break와 continue는 제일 가까이에 있는 반복문에만 영향을 준다.</p>
<hr>
<p>문제 다시보기</p>
<pre><code>문제 | input() 함수로 세 개의 float 값을 받은 후 세 변의 길이가 받은 float 값들인 삼각형이 존재 가능한지를 “YES” 또는 “NO”로 결과를 출력하도록 하세요.
입출력 예시 (볼드체: 프롬프트, 출력)
Length of side 1: 3
Length of side 2: 2
Length of side 3: 5
NO

힌트
- 삼각형이 만들어지기 위해서는 세 변 사이의 관계가 어떻게 형성되어야 할까요?
- 조건문을 사용해서 YES 혹은 NO를 출력시켜보세요.
- 대소문자에 유의하세요.</code></pre><p>답.</p>
<pre><code>side1 = float(input(&quot;Length of side 1: &quot;))
side2 = float(input(&quot;Length of side 2: &quot;))
side3 = float(input(&quot;Length of side 3: &quot;))
### 위의 파트는 남겨둔채 아래부터 코드를 작성하세요.


if side1 + side2 &gt; side3 and side1 + side3 &gt; side2 and side2 + side3 &gt; side1:
    print(&quot;YES&quot;)
else:
    print(&quot;NO&quot;)</code></pre><p>삼각형이 되려면, 아무 두 변을 더하면 나머지 변보다 커야 한다.</p>
<p>a + b &gt; c<br>a + c &gt; b<br>b + c &gt; a</p>
<p>이 세가지 조건이 모두 맞아야 삼각형이 된다.</p>
<hr>
<pre><code>문제 | input() 함수로 시작 자연수 a 와 끝 자연수 b를 받은 후, [a,b] 범위에 있는 3의 배수 혹은 5의 배수를 내림차순으로 출력하는 코드를 작성하세요.
입출력 예시 (볼드체: 프롬프트 및 출력)
Starting number: 10
End number: 21
21
20
18
15
12
10

힌트
- [a,b]는 a이상 b이하의 범위를 나타냅니다.
- 반복문과 조건문을 함께 활용해보세요.
- 내림차순이면 반복문을 어떻게 처리할까요?</code></pre><p>답.</p>
<pre><code>start = int(input(&quot;Starting number: &quot;))
end = int(input(&quot;End number: &quot;))
### 위의 파트는 남겨둔채 아래에 코드를 작성하세요.
for i in range(end, start - 1, -1):
    if i % 3 == 0 or i % 5 == 0:
        print(i)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[서초 AI 칼리지 데이터분석] - (8)]]></title>
            <link>https://velog.io/@hi_rice/%EC%84%9C%EC%B4%88-AI-%EC%B9%BC%EB%A6%AC%EC%A7%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B6%84%EC%84%9D-8</link>
            <guid>https://velog.io/@hi_rice/%EC%84%9C%EC%B4%88-AI-%EC%B9%BC%EB%A6%AC%EC%A7%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B6%84%EC%84%9D-8</guid>
            <pubDate>Sun, 18 May 2025 10:03:58 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hi_rice/post/f48a3e36-c10c-4fa3-9300-3f306a6713cc/image.png" alt=""></p>
<h3 id="matplotlib-vs-pandasplot">Matplotlib vs Pandas.plot)</h3>
<p>Pandas.plot() : 사용이 간편하다
    - 하지만, 축의 크기를 키우고 싶다면?
    - bar들의 간격을 더 줄이고 싶다면?
    - 색상을 주황색으로 바꾸고 싶다면?</p>
<ul>
<li>Matplotlib을 활용하면 Pandas Plot() 차트를 세부적으로 조정 가능</li>
<li>색상, 글자 크기 등 가시성이 좋은 자료를 생성</li>
<li>다중 그래프, 축 값 등의 변경 가능</li>
</ul>
<h3 id="matplotlib">Matplotlib</h3>
<ul>
<li>데이터 시각화와 2D 그래프 생성을 위한 파이썬
라이브러리</li>
<li>Pandas 데이터 프레임을 활용하여 여러가지 차트를
쉽게 생성 가능</li>
<li>여러가지 형식의 차트를 지원하며 커스텀이 가능</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/f199a35d-6d46-46c3-a8f3-9e49bf4ce466/image.png" alt=""></p>
<h3 id="matplotlib로-생성-가능한-plot">Matplotlib로 생성 가능한 Plot</h3>
<ul>
<li>Matplotlib은 Matlab에서 생성가능한 여러 타입의 그래프를 지원</li>
<li>기본차트 : 선, 산정도, 바 그래프 등</li>
<li>통계차트 : 히스토그램, 박스 플롯, 에러바 등</li>
<li>그외 : 3D, 좌표 데이터, 배열과 벡터 등</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/57ad831a-4dee-4481-9dac-9c55f795482a/image.png" alt=""></p>
<h3 id="matplotlib-기본-사용법">Matplotlib 기본 사용법</h3>
<ul>
<li>설치 및 환경 설정<ul>
<li>pip install matplotlib 을 통해 설치 가능</li>
</ul>
</li>
<li>matplotlib 불러오기 &amp; pyplot 서브패키지 사용<ul>
<li>import matplotlib.pyplot as pit</li>
</ul>
</li>
<li>주피터 노트북 환경에서 노트북에 차트를 저장하는 경우<ul>
<li>%matplotlibinline</li>
</ul>
</li>
<li>기본적인 함수의 호출은 pyplot에 그래프_이름()을 호출하는 식으로 작동<ul>
<li>예시 1) plt.plot() : default 는 line</li>
<li>예시 2) plt.scatter() : 산점도</li>
</ul>
</li>
<li>그래프 함수 호출 이후, 최종 적으로 차트를 출력하기 위해 pIt.show() 사용</li>
</ul>
<ul>
<li>그래프 함수 호출 이후, 최종 적으로 차트를 출력하기 위해 pIt.show() 사용<ul>
<li>plt.plot([1,4,9,16,251) #Line 차트 생성을 위해 array 넣기</li>
<li>plt.show() # 최종 Chart를 출력</li>
</ul>
</li>
<li>figure 단위로 관리 가능, 호출된 플롯 함수는 figure에 차트를 생성<ul>
<li>fig = plt.figure()</li>
</ul>
</li>
<li>최종 figure는 savefig() 함수를 통해 파일로 저장 가능<ul>
<li>fig.savefig(figure.png&#39;) #&#39;figure.png&#39; 파일로 저장</li>
</ul>
</li>
</ul>
<pre><code>fig = plt.figure()  # pyplot의 figure 객체 생성
plt.plot([1,2,3,4,5])   # Line 플롯으로 플롯 생성
plt.show()  # 생성된 플롯 출력
plt.savefig(&#39;figure.png&#39;)   # 생성된 플롯 파일로 저장</code></pre><h3 id="line-plot">Line Plot</h3>
<ul>
<li>데이터들을 선으로 연결한 Line Plot</li>
<li>Pandas 내장 시각화와 유사하게 plot() 함수 호출을 통해 사용<ul>
<li>함수 호출 : plt.plot([1,2,3,4])</li>
<li>차트 출력 : plt.show()</li>
</ul>
</li>
</ul>
<pre><code>plt.title(&#39;line plot&#39;)  # 차트 제목 설정
plt.plot([1,3,5,7,9])   # Line 차트 생성을 위해 array 넣기
plt.show()      # 최종 Chart를 출력</code></pre><p><img src="https://velog.velcdn.com/images/hi_rice/post/7946f3b8-d574-459c-a6c6-edf353f4aa55/image.png" alt=""></p>
<pre><code>plt.title(&#39;line plot&#39;)  # 차트 제목 설정
plt.plot([1,4,9,16,25])   # Line 차트 생성을 위해 array 넣기
plt.show()      # 최종 Chart를 출력</code></pre><p><img src="https://velog.velcdn.com/images/hi_rice/post/acbf1122-527e-4969-b81a-18c84fa9a7c9/image.png" alt=""></p>
<pre><code>plt.title(&#39;line plot&#39;)  # 차트 제목 설정
plt.plot(np.array([1,1.414, 1.732, 2, 2.236]))   # Line 차트 생성을 위해 array 넣기
plt.show()      # 최종 Chart를 출력</code></pre><p><img src="https://velog.velcdn.com/images/hi_rice/post/8d899890-034e-4094-8d34-f6ff7990fdd5/image.png" alt=""></p>
<pre><code>plt.title(&#39;line plot&#39;)  # 차트 제목 설정
plt.plot([1,3,5,7,9],[1,2,10,5,29])   # Line 차트 생성을 위해 array 넣기
plt.show()      # 최종 Chart를 출력</code></pre><p><img src="https://velog.velcdn.com/images/hi_rice/post/6ffe96ce-3da0-42d5-bd71-d46e21590d11/image.png" alt=""></p>
<ul>
<li>plot() 함수 내부에는 x값, 혹은 x,y 값을 넣어줄 수 있다</li>
<li>하나의 배열만 입력 : x는 1~N까지 자동으로 지정해서 플롯 생성</li>
<li>2개의 동일한 길이의 배열 입력 : 각 x에 따른 y 값들을 선으로 잇는 플롯 생성</li>
</ul>
<p>그 외의 함수 인자들</p>
<ul>
<li>c / color : Line의 색상을 설정한다.<ul>
<li>여러 Plot이 한 Figure에 있을 경우 자동으로 다른 색상으로 지정됨</li>
<li>하지만 임의로 색상을 지정하는 경우 color 인자 사용</li>
</ul>
</li>
</ul>
<pre><code>x = np.linspace(0, 10, 100)
fig = plt.figure()
plt.plot(x, np.sin(x), color=&#39;blue&#39;)    # 파란색 라인 생성
plt.plot(x, np.cos(x), color=&#39;m&#39;)   # 마젠타 색상 라인 생성
plt.show()</code></pre><p><img src="https://velog.velcdn.com/images/hi_rice/post/f70cb133-2f72-47cd-a479-5ce2ace4d07f/image.png" alt=""></p>
<pre><code>x = np.linspace(0, 10, 100)
fig = plt.figure()
plt.plot(x, np.sin(x), color=&#39;blue&#39;)    # 파란색 라인 생성
plt.plot(x, np.cos(x), color=&#39;m&#39;)   # 마젠타 색상 라인 생성
plt.show()</code></pre><p><img src="https://velog.velcdn.com/images/hi_rice/post/1028518f-40b8-49f3-b5db-7dbef9d166c1/image.png" alt=""></p>
<ul>
<li>marker</li>
<li>각 data point 의 표시를 커스텀 한다.</li>
<li>Options : . , OvX+ 등등</li>
</ul>
<pre><code>x = np.linspace(0, 10, 100)
fig = plt.figure()
plt.plot(x, np.sin(x), marker=&#39;.&#39;) # 점 마커 사용
plt.plot(x, np.cos(x), marker=&#39;o&#39;) # 원형 마커 사용
plt.show()</code></pre><ul>
<li>linestyle : 선의 모양을 설정</li>
<li>options : (실선, 기본값), -(대시선), (대시&amp;실선), (정선)</li>
</ul>
<pre><code>x = np.linspace(0, 10, 100)
fig = plt.figure()
plt.plot(x, np.sin(x), linestyle=&#39;--&#39;) # 대시선 사용
plt.plot(x, np.cos(x), linestyle=&#39;:&#39;) # 점선 사용
plt.show()</code></pre><p><img src="https://velog.velcdn.com/images/hi_rice/post/65950573-5a35-4c33-aaba-e7af7595134a/image.png" alt=""></p>
<h3 id="scatter-plot">Scatter Plot</h3>
<p>Scatter Plot (산점도) : 데이터 포인트를 하나의 점으로 나타내는 플롯</p>
<ul>
<li>plt.scatter() 함수를 호출하여 사용</li>
<li>입력으로는 x,y 값을 받아오며, x,y는 동일한 길이의 배열</li>
<li>각 x와 y 값에 대응되는 점을 플롯한다</li>
<li>기존 Plot() 함수로 동일한 결과물 생성도 가능</li>
</ul>
<p>함수 인자</p>
<ul>
<li>C: 각 점들의 색상 지정</li>
<li>하나의 색상으로 지정하거나</li>
<li>x,y 와 같은 길이의 배열 입력시, 각 점의 색상 지정</li>
</ul>
<pre><code>rng = np.random.RandomState(0)
x = rng.randn(100)  # 랜덤한 x값 100개 생성
y = rng.randn(100)  # 랜덤한 y값 100개 생성
plt.scatter(x,y,c = &#39;red&#39;)</code></pre><p><img src="https://velog.velcdn.com/images/hi_rice/post/138c9a87-bfdd-4c91-8b28-19f26be23c13/image.png" alt=""></p>
<ul>
<li>S: 각 점들의 반지름 설정</li>
<li>하나의 크기로 지정하거나</li>
<li>X,y 와 같은 길이의 배열 입력시, 각 점의 크기 지정</li>
</ul>
<pre><code>rng = np.random.RandomState(0)
x = rng.randn(5)  # 랜덤한 x값 5개 생성
y = rng.randn(5)  # 랜덤한 y값 5개 생성
colors = rng.randn(5)   # 랜덤한 색상값 5개 생성
sizes = rng.randn(5)*50    # 랜덤한 크기값 5개 생성
plt.scatter(x,y, s=sizes, c=colors)</code></pre><p><img src="https://velog.velcdn.com/images/hi_rice/post/594619a3-3b80-4422-b7e8-cf0b4e534afd/image.png" alt=""></p>
<h3 id="bar-plot">Bar Plot</h3>
<p>Bar Plot : 데이터 포인트의 수치를 막대로 표현</p>
<ul>
<li>plt.bar() 함수를 호출하여 사용</li>
<li>입력으로는 x, height 값을 받아오며, x,height는 동일한 길이의 배열</li>
<li>각x값에 대응되는 높이의 막대를 표현</li>
<li>추후 배울 tick 옵션을 활용해 문자열을 x 축으로 사용 가능</li>
</ul>
<pre><code>y = [2, 3, 1]
x = np.arange(len(y))
plt.title(&quot;Bar Chart&quot;)
plt.bar(x, y)</code></pre><p><img src="https://velog.velcdn.com/images/hi_rice/post/cec2b7f7-57e2-4591-ac50-390af221cbf0/image.png" alt=""></p>
<p>Options</p>
<ul>
<li>width : 막대의 너비를 설정</li>
<li>bottom : 막대의 시작점을 지정</li>
<li>color : 막대 색상 지정 가능</li>
</ul>
<pre><code>rng = np.random.RandomState(0)
x = [1,2,3,4]  # 랜덤한 x값 100개 생성
y = rng.randn(4)  # 랜덤한 y값 100개 생성
w = rng.randn(4)  # 랜덤한 width값 100개 생성
plt.bar(x,y,width=w, color = &#39;orange&#39;)</code></pre><p><img src="https://velog.velcdn.com/images/hi_rice/post/88105d9f-ea6f-470c-b7e8-92c8d124ffaa/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[서초 AI 칼리지 데이터분석] - (7)]]></title>
            <link>https://velog.io/@hi_rice/%EC%84%9C%EC%B4%88-AI-%EC%B9%BC%EB%A6%AC%EC%A7%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B6%84%EC%84%9D-7</link>
            <guid>https://velog.io/@hi_rice/%EC%84%9C%EC%B4%88-AI-%EC%B9%BC%EB%A6%AC%EC%A7%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B6%84%EC%84%9D-7</guid>
            <pubDate>Sat, 17 May 2025 18:20:01 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hi_rice/post/ec332f3f-c421-46e9-b597-1b5f06a7733c/image.png" alt=""></p>
<h2 id="데이터-시각화">데이터 시각화</h2>
<p>데이터 시각화</p>
<ul>
<li>데이터의 특징을 한눈에 표현하는 방법</li>
<li>데이터가 가진 특징을 가장 잘 표현할 수 있는 형식으로 시각화</li>
<li>각 상황에 맞게 필요한 정보를 정확하게 전달</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/61f6e029-bf72-4ff4-bc47-4bb1862c3c1c/image.png" alt=""></p>
<h3 id="좋은-데이터-시각화-나쁜-데이터-시각화">좋은 데이터 시각화? 나쁜 데이터 시각화?</h3>
<ul>
<li>데이터의 특징이 한 눈에 들어오는가?</li>
<li>시각화 유형, 그룹별 차이 등</li>
<li>너무 많은 정보를 담고 있는가?</li>
<li>가시성이 좋은가?</li>
<li>글자의 크기, 색상 조합 등</li>
<li>데이터가 깔끔한지?</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/ac32f0c7-0542-4bb7-a5dd-d05030f18223/image.png" alt=""></p>
<h3 id="pandas-visualization-functions">Pandas Visualization Functions</h3>
<ul>
<li>Line Chart : &#39;line&#39;</li>
<li>Bar Chart : &#39;bar&#39;</li>
<li>박스 차트 :&#39;box&#39;</li>
<li>파이 차트 : pie&#39;</li>
<li>산정도 : &#39;scatter&#39;</li>
<li>히스토그램 : &#39;his&#39;</li>
<li>커널 밀도 차트 : &#39;kde&#39;</li>
<li>Hexbin</li>
<li>...</li>
</ul>
<h3 id="pandas-visualization">Pandas Visualization</h3>
<p>실습을 위한 데이터 준비</p>
<ul>
<li>날짜 데이터</li>
</ul>
<pre><code>np.random.seed(0)
df1 = pd.DataFrame(np.random.randn(100, 3), # 2018.1.1 부터 100일간의 랜덤 숫자 세개 지정
                   index=pd.date_range(&#39;1/1/2018&#39;, periods=100),
                   columns=[&#39;A&#39;, &#39;B&#39;, &#39;C&#39;]).cumsum()
df1.tail()</code></pre><ul>
<li>Seaborn Iris &amp; Titatnic 데이터</li>
</ul>
<pre><code>iris = sns.load_dataset(&quot;iris&quot;)    # 붓꽃 데이터
titanic = sns.load_dataset(&quot;titanic&quot;)    # 타이타닉호 데이터</code></pre><h3 id="pandas-plot">Pandas Plot()</h3>
<p>Pandas 기본 Plot() 함수</p>
<ul>
<li>수치형 데이터프레임에서 plot() 함수를 실행</li>
<li>df.plot() 함수는 index를 기준으로 line graph 를 출력</li>
<li>Arguments of Plot()<ul>
<li>Kind : 그래프 타입을 결정. &#39;bar&#39;, &#39;box&#39;, 등</li>
<li>figsize : output 그림의 크기</li>
<li>fontsize : chart내 글자 크기</li>
</ul>
</li>
</ul>
<h3 id="pandas-plot---line">Pandas Plot - Line</h3>
<p>Line Chart</p>
<ul>
<li>Line 차트는 주로 연속적으로 변하는 수치형 자료를 표현</li>
<li>각 컬럼별 index값이 변함에 따라 수치가 변하는 것을 나타냄</li>
</ul>
<pre><code>df1.plot()  # 기본 선차트

plt.title(&quot;Pandas의 Plot메소드 사용 예&quot;)
plt.xlabel(&quot;시간&quot;)
plt.ylabel(&quot;Data&quot;)
plt.show()</code></pre><h3 id="pandas-plot---bar">Pandas Plot - Bar</h3>
<p>Bar Chart</p>
<ul>
<li>Bar 차트는 연속적인 선 차트와 달리 각 index 당 정확한 수치를 보여줌</li>
<li>하나/전체 컬럼에 대한 값을 그릴 수 있음</li>
<li>하나의 컬럼에 대한 graph</li>
</ul>
<pre><code>iris.sepal_length[:20].plot(kind=&#39;bar&#39;, rot=0)
plt.title(&quot;꽃받침의 길이 시각화&quot;)
plt.xlabel(&quot;Data&quot;)
plt.ylabel(&quot;꽃받침의 길이&quot;)
plt.show()</code></pre><ul>
<li>Kind=&#39;bar 이외에도 plot.bar() 형식으로 사용가능</li>
<li>하나/전체 컬럼에 대한 값을 그릴 수 있음</li>
<li>전체 컬럼에 대한 graph</li>
</ul>
<pre><code>iris[:5].plot.bar(rot=0)
plt.title(&quot;Iris 데이터의 Bar Plot&quot;)
plt.xlabel(&quot;Data&quot;)
plt.ylabel(&quot;각 Feature의 값&quot;)
plt.ylim(0, 7)
plt.show()</code></pre><h3 id="pandas-plot---barh">Pandas Plot - Barh</h3>
<p>Barh Chart</p>
<ul>
<li>kind = &#39;barh&#39; &amp; plot.barh()</li>
<li>수직이 아닌 수평 방향 막대 그래프 생성</li>
</ul>
<pre><code>iris[:5].plot.barh(rot=0)   # 수평 방향 막대그래프
plt.title(&quot;Iris 데이터의 Bar Plot&quot;)
plt.xlabel(&quot;Data&quot;)
plt.ylabel(&quot;각 Feature의 값&quot;)
plt.ylim(0, 7)
plt.show()</code></pre><h3 id="pandas-plot---bar-with-groupby">Pandas Plot - Bar (With groupby())</h3>
<p>Bar Chart</p>
<ul>
<li>데이터 전체의 통계치를 그래프로 그리기 위해 groupby() 활용</li>
<li>통계적 수치를 시각화하기 위해 통계함수를 적용한 데이터프레임 생성</li>
</ul>
<pre><code>df2 = iris.groupby(iris.species).mean() # species 에 다른 각 수치별 평균값의 차이
df2.columns.name = &quot;feature&quot;
df2</code></pre><h3 id="pandas-plot---bar-with-groupby-1">Pandas Plot - Bar (With groupby())</h3>
<p>Bar Chart</p>
<ul>
<li>데이터 전체의 통계치를 그래프로 그리기 위해 groupby() 활용</li>
<li>통계적 수치를 시각화하기 위해 통계함수를 적용한 데이터프레임 생성</li>
<li>표본들의 컬럼에 따른 통계적 수치를 시각화</li>
</ul>
<pre><code>df2.plot.bar(rot=0) # 새롭게 정의된 데이터에 대해 바 그래프
plt.title(&quot;각 종의 Feature별 평균&quot;)
plt.xlabel(&quot;평균&quot;)
plt.ylabel(&quot;종&quot;)
plt.ylim(0, 8)
plt.show()</code></pre><h3 id="pandas-plot---pie">Pandas Plot - Pie</h3>
<p>Pie Chart</p>
<ul>
<li>kind = &#39;pie&#39;</li>
<li>특정 컬럼 내에서 category가 차지하는 비율을 시각화</li>
<li>그룹간의 차이가 명확할 수록 가시성 좋음</li>
<li>그룹의 수가 과도하게 많지 않은 컬럼에 대해 적용</li>
</ul>
<pre><code>df3 = titanic.pclass.value_counts() # value_counts 를 통해 pclass 마다의 인원수
df3.plot(kind=&#39;pie&#39;,autopct=&#39;%.2f%%&#39;)
plt.title(&quot;선실별 승객 수 비율&quot;)
plt.axis(&#39;equal&#39;)
plt.show()</code></pre><h3 id="pandas-plot---histogram">Pandas Plot - Histogram</h3>
<p>Histogram</p>
<ul>
<li>kind = &#39;hist&#39; | plot.hist)</li>
<li>전체 데이터의 분포를 시각화</li>
<li>연속성 데이터를 사용자가 지정한 범위로 압축</li>
<li>그래프의 개형을 통해 어느 구간에 표본이 집중되는지</li>
</ul>
<pre><code>iris.plot.hist()    # plot.hist()로 히스토그램 생성
plt.title(&quot;각 Feature 값들의 빈도수 Histogram&quot;)
plt.xlabel(&quot;데이터 값&quot;)
plt.show()</code></pre><h3 id="pandas-plot---kde">Pandas Plot - KDE</h3>
<p>커널 밀도 함수(KDE)</p>
<ul>
<li>kind = &#39;kde&#39; | plot.kde()</li>
<li>히스토그램이 박스 단위로 분포를 보였다면, 연속적인 분포를 확인</li>
<li>분포에 근사한 커널 밀도 함수의 개형을 제공</li>
</ul>
<pre><code>iris.plot.kde() # 커널 밀도 함수 생성
plt.title(&quot;각 Feature 값들의 빈도수에 대한 Kernel Density Plot&quot;)
plt.xlabel(&quot;데이터 값&quot;)
plt.show()</code></pre><h3 id="pandas-plot---box">Pandas Plot - Box</h3>
<p>Box Chart</p>
<ul>
<li>kind = &#39;box&#39; | plot.box)</li>
<li>각 컬럼별 표본의 분포를 박스의 형태로 나타냄</li>
<li>각 박스는 1~4 분위값, 평균값, 최대/최소 값을 한번에 전달</li>
<li>다양한 분포 정보를 쉽게 전달함</li>
</ul>
<pre><code>iris.plot.box()
plt.title(&quot;각 Feature 값들의 빈도수에 대한 Box Plot&quot;)
plt.xlabel(&quot;Feature&quot;)
plt.ylabel(&quot;데이터 값&quot;)
plt.show()</code></pre><h3 id="recap--titanic-데이터-분석">Recap : Titanic 데이터 분석</h3>
<p>Titanic 데이터에서 확인했던 차이들을 Pandas plot으로 표현해보자</p>
<ul>
<li>pclass 와 사용한 Fare을 여러 차트로 표현해보자</li>
<li>Sex와 Survived의 counts 를 표현해보자</li>
<li>Pie Chart로 각 성별 생존 비율을 그려보자</li>
<li>나이를 구간이 아닌 범주형으로 바꾸어 특징을 그려보자</li>
</ul>
<h3 id="pandas-plot---scatter">Pandas Plot - Scatter</h3>
<p>Scatter Chart (산점도)</p>
<ul>
<li>kind = &#39;scatter&#39;</li>
<li>표본의 각 하나의 데이터를 점에 대응시켜 좌표에 나타냄</li>
<li>각 점들의 분포를 여러 축으로 확장하여 관찰 가능</li>
<li>단 너무 많은 데이터를 그릴 시 가독성이 떨어질 수 있음.</li>
<li>2차원 차트이기 때문에 x와 y 값을 입력받음</li>
</ul>
<pre><code>iris.plot.scatter(x=&#39;sepal_length&#39;,y=&#39;sepal_width&#39;)  # sepal_length와 width의 관계를 산점도로 표현
plt.title(&quot;각 Feature의 종 별 데이터에 대한 SCatter Plot&quot;)
plt.show()</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[서초 AI 칼리지 데이터분석] - (6)]]></title>
            <link>https://velog.io/@hi_rice/%EC%84%9C%EC%B4%88-AI-%EC%B9%BC%EB%A6%AC%EC%A7%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B6%84%EC%84%9D-6</link>
            <guid>https://velog.io/@hi_rice/%EC%84%9C%EC%B4%88-AI-%EC%B9%BC%EB%A6%AC%EC%A7%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B6%84%EC%84%9D-6</guid>
            <pubDate>Fri, 16 May 2025 18:13:19 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hi_rice/post/314fc208-1ad6-42d8-bf07-a81001eedc97/image.png" alt=""></p>
<h2 id="pandas-데이터프레임-활용---2">Pandas 데이터프레임 활용 - (2)</h2>
<ul>
<li>시계열 데이터 다루기 : datetime, dt.date(), dt.time()</li>
<li>외부 함수 적용하기 : apply(), assign()</li>
</ul>
<h3 id="시계열-데이터-다루기">시계열 데이터 다루기</h3>
<ul>
<li>Pandas는 시계열 데이터를 지원</li>
<li>pandas 시계열 자료형 : datetime, time, date 등</li>
<li>pd.to_datetime() : 입력받은 string을 datetime으로 변환</li>
<li>변환된 datetime() 객체는 서로 빼거나 더해 timedeltal) 단위로 계산이 가능해진다</li>
<li>pd.date_range(start, end) : start 부터 end 시간 까지의 시간 범위를 생성</li>
</ul>
<pre><code>date_str = [&quot;2020, 1, 1&quot;, &quot;2020, 1, 3&quot;, &quot;2020, 1, 5&quot;, &quot;2020, 1, 7&quot;]
idx = pd.to_datetime(date_str)
idx</code></pre><pre><code>print(pd.date_range(&quot;2020-1-1&quot;, &quot;2020-1-15&quot;))      # 1월1일부터 1월15일까지의 시간 범위
print(pd.date_range(start=&quot;2020-1-1&quot;, periods=15))     # 1월1일부터 15일간의 시간 범위</code></pre><h3 id="데이터-프레임의-함수-연산">데이터 프레임의 함수 연산</h3>
<ul>
<li>칼럼들에 연산 적용하기 : apply()</li>
<li>하나/다수의 칼럼에 복잡한 연산이 필요한 경우 : 자체적으로 함수를 정의</li>
<li>정의된 함수와 연산을 apply(func) 를 통해 적용</li>
<li>Arguments<ul>
<li>첫 인자는 사전 정의된 작동될 함수의 이름</li>
<li>그이후 인자는 작동될 함수의 인자를 따름</li>
</ul>
</li>
</ul>
<pre><code>def plus(x):
    return x.sepal_length + x.petal_length  # iris의 길이를 모두 더함

iris[&#39;length_sum&#39;] = iris.apply(plus,axis=1)    #인자로 plus 함수를 넣는다.
iris.length_sum.head()</code></pre><h3 id="새로운-열-생성--assign">새로운 열 생성 : assign()</h3>
<ul>
<li>이미 존재하는 열을 기반으로 새로운 열을 정의할때 사용</li>
<li>assign(새로운_열의_이름 = 수식)의 형식으로 사용</li>
<li>주로 수식은 람다식을 사용</li>
</ul>
<pre><code>iris.assign(length_sum=lambda x:x.sepal_length + x.petal_length)    #인자로 새로운 열 이름과 수식을 제공
iris.length_sum.head()</code></pre><h3 id="pandas를-활용한-실전-데이터-분석">Pandas를 활용한 실전 데이터 분석</h3>
<p>Titanic Dataset</p>
<ul>
<li>Kaggle Dataset : 20000 &lt; N (<a href="https://www.kaggle.com/c/titanic/">https://www.kaggle.com/c/titanic/</a>)</li>
<li>타이타닉호의 승객의 정보를 통해 임의의 사람들의 실종 여부를 맞추는 문제</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/7b8043fe-cb96-427f-b700-fb9f8342ca80/image.png" alt=""></p>
<ul>
<li>총 10개의 컬럼</li>
<li>생존 여부, 성별, 나이, 티켓 등급</li>
<li>문자열, 숫자 등 다양한 자료형 포함</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/2f992ab9-ebaa-479f-847b-50bdd04a506b/image.png" alt=""></p>
<p>Titanic 데이터 불러오기</p>
<ul>
<li>Iris 데이터와 유사하게 Seaborn 라이브러리에서 불러오기</li>
</ul>
<pre><code>import seaborn as sns
data = sns.load_dataset(&#39;titanic&#39;)   #titanic 데이터셋 불러오기
data.head()</code></pre><p><img src="https://velog.velcdn.com/images/hi_rice/post/6216c8a5-f61d-4b3f-a222-0f7383dc23cd/image.png" alt=""></p>
<ul>
<li>불러온 titanic 데이터 info() 살펴보기</li>
<li>총 14개의 열을 가지고 있음</li>
<li>int, float, object, category 등의 자료형</li>
<li>모든 열의 element 수가 동일하지는 않음</li>
</ul>
<pre><code>titanic.info()</code></pre><p><img src="https://velog.velcdn.com/images/hi_rice/post/bd2e7123-be2c-4737-9517-ea3563a2e238/image.png" alt=""></p>
<p>Titanic 데이터 분석 Missions</p>
<ol>
<li>중복치 처리를 진행해보자</li>
<li>결측치를 처리해보자</li>
<li>각 숫자형 데이터들의 통계치를 구해보자</li>
<li>Category 형 데이터에 groupby를 적용해보자</li>
<li>String Type 열에도 agg()를 적용해보자</li>
<li>Cabin을 여러개의 열로 분할해보자</li>
<li>나만의 경향성을 찾아보자</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 스터디 4회차 - (10)]]></title>
            <link>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-10</link>
            <guid>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-10</guid>
            <pubDate>Fri, 16 May 2025 17:13:29 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hi_rice/post/5e047e71-f08d-4fe5-abdc-5d90561f5dbe/image.jpeg" alt=""></p>
<h2 id="53-비선형-자료-구조">5.3 비선형 자료 구조</h2>
<p>비선형 자료 구조란 일렬로 나열하지 않고 자료 순서나 관계가 복잡한 구조를 말한다. 일반적으로 트리나 그래프를 말한다.</p>
<h3 id="531-그래프">5.3.1 그래프</h3>
<p>그래프는 정점과 간선으로 이루어진 자료구조를 말한다.</p>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/ccd6fabb-3b24-478d-b1d4-51e95be77b89/image.png" alt=""></p>
<ul>
<li>정점(Vertex): 그래프에서 하나의 개체를 나타내는 점으로 표현한다.</li>
<li>간선(Edge): 정점과 정점 사이를 연결하는 선으로 표현된다.<ul>
<li>단방향 간선(Directed Edge): 방향성이 있는 간선이다.</li>
<li>양방향 간선(Undirected Edge): 방향성이 없는 간선이다.</li>
</ul>
</li>
</ul>
<ul>
<li>outdegree: 특정 정점에서 나가는 간선의 개수이다.</li>
<li>indegree: 특정 정점으로 들어오는 간선의 개수이다.</li>
</ul>
<p>가중치(Weight): 그래프의 간선에 부여된 값으로 해당 간선을 통해 이동하는 비용이나 거리를 나타낸다.</p>
<h3 id="532-트리tree">5.3.2 트리(Tree)</h3>
<ul>
<li>그래프 중 하나로 그래프의 특징처럼 정점과 간선으로 이루어져 있다.</li>
<li>트리 구조로 배열된 일종의 계층적 데이터 집합이다.</li>
<li>루트 노드, 내부 노드, 리프 노드 등으로 구성된다.</li>
</ul>
<blockquote>
<p>루트 노드(Root Node): 트리의 최상단에 위치해서 부모가 없는 노드
내부 노드(Internal Node): 루트 노드와 리프 노드 사이에 있는 노드
리프 노드(Leaf Node): 트리의 끝단에 위치해서 자식이 없는 노드</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/59141a61-d8e1-4f2c-b960-6995670308e4/image.png" alt=""></p>
<h3 id="트리의-특징">트리의 특징</h3>
<p>트리는 그래프의 일종이며 다음 특징을 가진다는 점이 다르다.</p>
<ul>
<li>부모, 자식 계층 구조를 가진다.</li>
<li>같은 경로 상에서 어떤 노드보다 위에 있으면 부모 노드, 아래에 있으며 자식 노드가 된다.</li>
<li>간선의 수 = 노드의 수 - 1 이다.</li>
<li>트리 내의 어떤 노드와 어떤 노드까지의 경로는 반드시 존재한다.</li>
</ul>
<h4 id="트리의-구성">트리의 구성</h4>
<p>트리는 루트 노드, 내부 노드, 리프 노드로 이루어져 있다.</p>
<h4 id="루트-노드">루트 노드</h4>
<p>가장 위에 있는 노드.
보통 트리 문제가 나오고 트리를 탐색할 때 루트 노드를 중심으로 탐색하면 문제가 쉽게 풀리는 경우가 많다.</p>
<h4 id="내부-노드">내부 노드</h4>
<p>루트 노드와 리프 노드 사이에 있는 노드.</p>
<h4 id="리프-노드">리프 노드</h4>
<p>리프 노드는 자식 노드가 없는 노드.</p>
<h3 id="트리의-높이와-레벨">트리의 높이와 레벨</h3>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/c014ec7c-4887-4eb8-ac1b-78e5ed2df79f/image.png" alt=""></p>
<ul>
<li>깊이(Depth): 루트 노드부터 특정 노드까지 최단 거리로 갔을 때의 거리이다.</li>
<li>높이(Height): 루트 노드로부터 리프 노드까지 거리 중 가장 긴 거리이다.</li>
<li>레벨(Level): 트리 계층 구조에서 각 층을 나타낸다. 보통 깊이와 같은 의미를 가진다.</li>
<li>서브트리(Subtree): 트리 내에 있는 부분집합을 의미한다.</li>
</ul>
<h3 id="이진-트리">이진 트리</h3>
<p>이진 트리는 자식의 노드 수가 두 개 이하인 트리를 의미한다.</p>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/ffad1fcc-8939-4e73-be85-c27d1dadad39/image.png" alt=""></p>
<ul>
<li>정이진 트리(full binary tree): 자식 노드가 0 또는 두 개인 이진 트리이다.</li>
<li>완전 이진 트리(complete binary tree): 왼쪽에서부터 채워져 있는 이진 트리이다.</li>
<li>변질 이진 트리(degenerate binary tree): 자식 노드가 하나밖에 없는 이진 트리이다.</li>
<li>포화 이진 트리(perfect binary tree): 모든 노드가 꽉 차 있는 이진 트리이다.</li>
<li>균형 이진 트리(balanced binary tree): 왼쪽과 오른쪽 노드의 높이 차이가 1 이하인 이진 트리이다.</li>
</ul>
<h3 id="이진-탐색-트리">이진 탐색 트리</h3>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/607bd491-1190-4d76-b536-1658d800fa82/image.png" alt=""></p>
<ul>
<li>노드의 왼쪽 하위 트리에는 노드 값보다 작은 값이 있는 노드만 포함된다.</li>
<li>노드의 오른쪽 하위 트리에는 노드 값보다 큰 값이 있는 노드만 포함된다.</li>
</ul>
<h4 id="비선형적-이진-탐색-트리와-선형적-이진-탐색-트리">비선형적 이진 탐색 트리와 선형적 이진 탐색 트리</h4>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/1cac999a-392f-4129-abdd-725d871b9048/image.png" alt=""></p>
<p>이진 탐색 트리는 특정 순서로 요소를 삽입하면 트리의 구조가 달라질 수 있다.</p>
<ul>
<li>비선형적 이진 탐색 트리(Non-linear Binary Search Tree): 보통 요소를 찾을 때 O(logn)이 걸린다.</li>
<li>선형적 이진 탐색트리(Linear Binary Search Tree): 최악의 경우 O(n)이 걸린다.</li>
</ul>
<h3 id="avl-트리">AVL 트리</h3>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/116f70d3-a470-4c1f-902f-09efa5a9fe62/image.png" alt=""></p>
<ul>
<li>선형적인 트리가 되는 것을 방지하고자 스스로 균형을 잡는 이진 탐색 트리이다.</li>
<li>두 자식 서브트리의 높이는 항상 최대 1만큼 차이 난다.</li>
<li>탐색, 삽입, 삭제 모두 시간 복잡도가 O(logn)이다.</li>
</ul>
<h3 id="레드-블랙-트리">레드 블랙 트리</h3>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/e7aecc4e-2e7a-4f8b-a52c-159295f84214/image.png" alt=""></p>
<ul>
<li>각 노드는 빨간색 또는 검은색의 색상을 나타내는 추가 비트를 저장하며,  삽입 및 삭제 중에 트리가 균형을 유지하도록 하는 데 사용된다.</li>
<li>모든 리프 노드와 루트 노드는 블랙이고 어떤 노드가 레드이면 그 노드의 자식은 반드시 블랙이다.</li>
<li>탐색, 삽입, 삭제 모두 시간 복잡도가 O(logn)이다.</li>
</ul>
<h3 id="533-힙heap">5.3.3 힙(Heap)</h3>
<p>힙은 완전 이진 트리 기반의 자료 구조이며, 최소힙과 최대힙 두 가지가 있고 해당 힙에 따라 특정한 특징을 지킨 트리를 말한다.</p>
<pre><code>- 최대힙: 루트 노드에 있는 키는 모든 자식에 있는 키 중에서 가장 커야 한다.
- 최소힙: 루트 노드에 있는 키는 모든 자식에 있는 키 중에서 가장 작아야 한다.</code></pre><p>최대힙과 최소힙 모두 특정 노드에서 자식 노드와의 관계도 해당 특징이 재귀적으로 이루어져야 한다.</p>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/d797c87b-003f-4814-9efe-02c6e4567459/image.png" alt=""></p>
<h3 id="최대힙의-삽입">최대힙의 삽입</h3>
<ol>
<li>새로운 요소를 힙의 마지막 노드에 추가한다.</li>
<li>새로운 요소를 부모 노드들과 비교하며, 부모 노드보다 크다면 두 노드를 교환한다. 이를 반복하여 새로운 요소가 자신의 위치를 찾을 때까지 진행한다.</li>
<li>힙의 성질을 만족할 때까지 계속해서 요소를 부모 노드와 비교하며 교환하는 과정을 반복한다.</li>
</ol>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/bed9d3b1-8e01-4314-ba0f-01efac0798ab/image.png" alt=""></p>
<h3 id="최대힙의-삭제">최대힙의 삭제</h3>
<ol>
<li>최대힙에서 최댓값은 항상 루트 노드에 위치하게 된다.</li>
<li>루트 노드를 삭제하고, 힙의 마지막 노드를 루트 노드의 위치로 가져온다.</li>
<li>새로운 루트 노드를 자식 노드들과 비교하며, 두 자식 노드 중 더 큰 값과 비교하여 자식 노드와 교환한다. 이를 반복하여 새로운 루트 노드가 자신의 위치를 찾을 때까지 진행한다.</li>
<li>힙의 성질을 만족할 때까지 계속해서 노드를 자식 노드와 비교하며 교환하는 과정을 반복한다.</li>
</ol>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/153a5e40-41b1-4793-ae24-0f87f467228f/image.png" alt=""></p>
<h3 id="534-우선순위-큐priority-queue">5.3.4 우선순위 큐(Priority Queue)</h3>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/a33b50fd-c36c-43c7-82aa-e939855a24c2/image.png" alt=""></p>
<ul>
<li>우선순위 큐는 일반적으로 힙(heap)이라는 자료 구조를 기반으로 구현된다.</li>
<li>우선순위 대기열이라고도 한다. 우선순위에 따라 작업이나 요소를 처리하는 대기열을 의미한다.</li>
<li>대기열에서 우선순위가 높은 요소가 우선순위가 낮은 요소보다 먼저 제공되는 자료 구조이다.</li>
</ul>
<h3 id="535-맵map">5.3.5 맵(Map)</h3>
<ul>
<li>맵은 키와 값을 쌍으로 저장하는 자료 구조이다. 하나의 키는 하나의 값에 대응된다.</li>
<li>맵에서 키는 유일해야 한다. 값에 접근하거나 값을 변경하는데 사용되기 때문이다.</li>
<li>맵은 중복된 값을 허용한다. 서로 다른 키에 대해 같은 값을 가질 수 있다는 의미이다.</li>
<li>주로 String : int 형태로 값을 할당해야할 때 사용한다.</li>
<li>자바에서 Map을 사용하기 위해 HashMap과 TreeMap 등의 클래스를 활용한다.</li>
</ul>
<blockquote>
<ul>
<li>HashMap
해시 기반으로 요소를 저장한다. 순서가 중요하지 않은 경우에 사용된다.
검색, 삽입, 삭제에 평균적으로 O(1)의 시간 복잡도를 가진다.</li>
</ul>
</blockquote>
<ul>
<li>TreeMap:
요소를 정렬된 순서로 저장한다. 정렬된 집합을 필요로 할 때 사용된다.
삽입, 조회, 수정, 삭제의 연산에 O(log n)의 시간 복잡도를 가진다.</li>
</ul>
<h3 id="536-셋set">5.3.6 셋(Set)</h3>
<ul>
<li>셋은 동일한 요소를 중복해서 저장하지 않는 자료 구조이다. 동일한 값을 가진 요소를 추가하려고 하면 무시된다.</li>
<li>주로 중복을 제거하고 고유한 값만을 유지하려는 경우에 사용된다.</li>
<li>자바에서 Set을 사용하기 위해 HashSet과 TreeSet 등의 클래스를 활용한다.</li>
</ul>
<blockquote>
<ul>
<li>HashSet:
해시 기반으로 요소를 저장한다. 순서가 중요하지 않은 경우에 사용된다.
검색, 삽입, 삭제에 평균적으로 O(1)의 시간 복잡도를 가진다.</li>
</ul>
</blockquote>
<ul>
<li>TreeSet:
요소를 정렬된 순서로 저장한다. 정렬된 집합을 필요로 할 때 사용된다.
삽입, 조회, 수정, 삭제의 연산에 O(log n)의 시간 복잡도를 가진다.</li>
</ul>
<h3 id="537-해시-테이블">5.3.7 해시 테이블</h3>
<ul>
<li>해시 테이블은 무한에 가까운 데이터들을 유한한 개수의 해시 값으로 매핑한 테이블이다.</li>
<li>삽입, 삭제, 탐색 시 평균적으로 O(1)의 시간 복잡도를 가지며 unordered_map으로 구현한다.</li>
<li>작은 크기의 캐시 메모리로도 프로세스를 관리하도록 할 수 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 스터디 4회차 - (9)]]></title>
            <link>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-9</link>
            <guid>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-9</guid>
            <pubDate>Fri, 16 May 2025 16:07:11 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hi_rice/post/93fd873a-b50b-484b-a9a9-8cf4ddcd631a/image.jpeg" alt=""></p>
<h2 id="52-선형-자료-구조">5.2 선형 자료 구조</h2>
<p>선형 자료 구조란 요소가 일렬로 나열되어 있는 자료 구조를 말한다.</p>
<h3 id="521-연결-리스트linked-list">5.2.1 연결 리스트(Linked List)</h3>
<p>연결 리스트란,</p>
<ul>
<li>데이터를 감싼 노드를 포인터로 연결해서 공간적인 효율성을 극대화시킨 자료 구조이다.</li>
<li>삽입과 삭제가 O(1)이 걸리며 탐색에는 O(n)이 걸린다.</li>
</ul>
<p>데이터의 삽입과 삭제가 빈번하게 일어나는 경우에는 유용하게 이용될 수 있으나, 특정 노드에 빠르게 접근하는 것이 어렵기 때문에 빠른 검색이 중요한 상황에서는 다른 자료 구조를 고려할 필요가 있다.</p>
<h4 id="연결-리스트의-종류">연결 리스트의 종류</h4>
<p>노드들 간의 연결 방식과 구성에 따라 크게 세 가지로 나뉜다.</p>
<blockquote>
<p>싱글 연결 리스트 : next 포인터만 가진다.
이중 연결 리스트 : next 포인터와 prev 포인터를 가진다.
원형 이중 연결 리스트 : 마지막 노드의 next 포인터가 헤드 노드를 가리킨다.</p>
</blockquote>
<h3 id="522-배열array">5.2.2 배열(Array)</h3>
<p>배열이란,</p>
<ul>
<li>같은 타입의 변수들로 이루어져 있다.</li>
<li>크기가 정해져있다.</li>
<li>인접한 메모리 위치에 있는 데이터를 모아놓은 집합이다.</li>
<li>중복을 허용하고 순서가 있다.</li>
<li>탐색에는 O(1)이 걸리고 삽입과 삭제에는 O(n)이 걸린다.</li>
</ul>
<p>연결 리스트와 반대되는 특징으로, 데이터 삽입과 삭제가 빈번하게 일어나는 경우에는 연결 리스트를 탐색이 빈번하게 일어나는 경우에는 배열을 사용하는 것이 좋다.</p>
<h4 id="랜덤-접근과-순차적-접근">랜덤 접근과 순차적 접근</h4>
<ul>
<li>랜덤 접근은 임의의 인덱스에 해당하는 데이터에 직접 접근할 수 있는 기능이다.</li>
<li>순차적 접근은 데이터를 저장된 순서대로 검색할 수 있는 기능이다.</li>
</ul>
<h4 id="배열과-연결-리스트-비교">배열과 연결 리스트 비교</h4>
<ul>
<li>배열은 탐색이 빠르고, 데이터 추가 및 삭제는 느리다.</li>
<li>연결리스트는 탐색이 느리나, 데이터 추가 및 삭제는 빠르다.</li>
</ul>
<h3 id="523-벡터vector">5.2.3 벡터(Vector)</h3>
<p>벡터란,</p>
<ul>
<li>동적으로 요소를 할당할 수 있는 동적 배열이다.</li>
<li>중복을 허용하고 순서가 있으며 랜덤 접근이 가능하다.</li>
<li>탐색과 맨 뒤의 요소를 삽입하고 삭제하는 데 O(1)이 걸린다.</li>
<li>맨 앞과 맨 뒤가 아닌 요소를 삽입하고 삭제하는 데 O(n)이 걸린다.</li>
</ul>
<p>데이터의 삽입과 삭제가 맨 앞이나 맨 뒤에 이루어지는 경우에는 빠른 성능을 보이지만, 중간에 요소를 삽입하거나 삭제하는 경우에는 성능이 떨어질 수 있다.</p>
<h3 id="524-스택stack">5.2.4 스택(Stack)</h3>
<p>스택이란, </p>
<ul>
<li>LIFO(Last In First Out) 성질을 가진 자료 구조이다.</li>
<li>삽입 및 삭제에 O(1)이 걸리고 탐색에 O(n)이 걸린다.</li>
<li>재귀적인 함수, 알고리즘에 사용되며 웹 브라우저 방문 기록 등에 쓰인다.</li>
</ul>
<h3 id="525-큐queue">5.2.5 큐(Queue)</h3>
<p>큐란,</p>
<ul>
<li>FIFO(First In First Out) 성질을 지닌 자료 구조이다.</li>
<li>삽입 및 삭제에 O(1)이 걸리고 탐색에 O(n)이 걸린다.</li>
<li>CPU 작업을 기다리는 프로세스, 스레드 행렬 또는 네트워크 접속을 기다리는 행렬, 너비 우선 탐색, 캐시 등에 사용된다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 스터디 4회차 - (8)]]></title>
            <link>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-8</link>
            <guid>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-8</guid>
            <pubDate>Fri, 16 May 2025 16:02:13 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hi_rice/post/dd9f9b98-7654-4a42-ab09-d16e481cb823/image.jpeg" alt=""></p>
<blockquote>
<p>자료구조는 효율적으로 데이터를 관리하고 수정, 삭제, 탐색, 저장할 수 있는 데이터 집합을 말한다.</p>
</blockquote>
<h2 id="51-복잡도">5.1 복잡도</h2>
<h3 id="511-시간-복잡도">5.1.1 시간 복잡도</h3>
<ul>
<li>문제를 해결하는 데 걸리는 시간과 입력의 함수 관계이다.</li>
<li>어떠한 알고리즘의 로직이 얼마나 오랜 시간이 걸리는지를 나타내는 데 쓰인다.</li>
<li>빅오 표기법으로 나타낸다.</li>
<li>입력 범위 n을 기준으로 해서 로직이 몇 번 반복되는 지 나타내는 것이다.</li>
<li>효율적인 코드로 개선하는 데 쓰이는 척도가 된다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/147d59df-953b-47f8-8997-054579b3c4b4/image.png" alt=""></p>
<h3 id="512-공간-복잡도">5.1.2 공간 복잡도</h3>
<ul>
<li>프로그램을 실행시켰을 때 필요로 하는 자원 공간의 양을 말한다.</li>
<li>정적 변수로 선언된 것 말고도 동적으로 재귀적인 함수로 인해 공간을 계속해서 필요로 할 경우도 포함된다.</li>
</ul>
<h3 id="513-자료-구조에서의-시간-복잡도">5.1.3 자료 구조에서의 시간 복잡도</h3>
<p>자료구조를 쓸 때는 이러한 시간 복잡도를 잘 생각해야 한다.</p>
<p>&lt; 자료 구조의 평균 시간 복잡도 &gt;</p>
<table>
<thead>
<tr>
<th>자료 구조</th>
<th>접근</th>
<th>탐색</th>
<th>삽입</th>
<th>삭제</th>
</tr>
</thead>
<tbody><tr>
<td>배열(array)</td>
<td>O(1)</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(n)</td>
</tr>
<tr>
<td>스택(stack)</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(1)</td>
<td>O(1)</td>
</tr>
<tr>
<td>큐(queue)</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(1)</td>
<td>O(1)</td>
</tr>
<tr>
<td>이중 연결 리스트(doubly linked list</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(1)</td>
<td>O(1)</td>
</tr>
<tr>
<td>해시 테이블(hash table</td>
<td>O(1)</td>
<td>O(1)</td>
<td>O(1)</td>
<td>O(1)</td>
</tr>
<tr>
<td>이진 탐색 트리(BST)</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
</tr>
<tr>
<td>AVL 트리</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
</tr>
<tr>
<td>레드 블랙 트리</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
</tr>
</tbody></table>
<p>&lt; 자료 구조 최악의 시간 복잡도 &gt;</p>
<table>
<thead>
<tr>
<th>자료 구조</th>
<th>접근</th>
<th>탐색</th>
<th>삽입</th>
<th>삭제</th>
</tr>
</thead>
<tbody><tr>
<td>배열(array)</td>
<td>O(1)</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(n)</td>
</tr>
<tr>
<td>스택(stack)</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(1)</td>
<td>O(1)</td>
</tr>
<tr>
<td>큐(queue)</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(1)</td>
<td>O(1)</td>
</tr>
<tr>
<td>이중 연결 리스트(doubly linked list</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(1)</td>
<td>O(1)</td>
</tr>
<tr>
<td>해시 테이블(hash table</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(n)</td>
</tr>
<tr>
<td>이진 탐색 트리(BST)</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(n)</td>
</tr>
<tr>
<td>AVL 트리</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
</tr>
<tr>
<td>레드 블랙 트리</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 스터디 4회차 - (7)]]></title>
            <link>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-7</link>
            <guid>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-7</guid>
            <pubDate>Fri, 16 May 2025 15:46:37 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hi_rice/post/e7f3ac31-bf95-488b-98de-56ff747e5ef6/image.jpeg" alt=""></p>
<h2 id="47-조인의-원리">4.7 조인의 원리</h2>
<h3 id="471-중첩-루프-조인">4.7.1 중첩 루프 조인</h3>
<p>중첩 루프 조인 (NLJ, Nested Loop Join)이란, 
중첩 for 문과 같은 원리로 조건에 맞는 조인을 하는 방법이다.
랜덤 접근에 대한 비용이 많이 증가하므로 대용량의 테이블에서는 사용하지 않는다.</p>
<pre><code>for each row in t1 matching reference key {
    for each row in t2 matching reference key { 
        if row satisfies join conditions, send to client 
    }
}</code></pre><p>중첩 루프 조인에서 발전한 블록 중첩 루프 조인(BNL, Block Nested Loop) 방식도 있다.
조인할 테이블을 작은 블록으로 나눠서 블록 하나씩 조인</p>
<h3 id="472-정렬-병합-조인">4.7.2 정렬 병합 조인</h3>
<p>정렬 병합 조인이란,
각각의 테이블을 조인할 필드 기준으로 정렬하고, 정렬이 끝난 이후에 조인 작업을 수행하는 조인이다.</p>
<p>조인할 때 쓸 적절한 인덱스가 없을 때, 대용량의 테이블을 조인할 때, 조인 조건으로 &lt; , &gt; 등 범위 비교 연산자가 있을 때 쓴다.</p>
<h3 id="473-해시-조인">4.7.3 해시 조인</h3>
<p>해시 조인 이란,
해시 테이블을 기반으로 조인하는 방법이다.</p>
<p>하나의 테이블이 메모리에 온전히 들어간다면 보통 중첩 루프 조인보다 더 효율적임이다.</p>
<ul>
<li>동등(=) 조건에서만 사용 가능</li>
<li>MySQL의 해시 조인 단계는 빌드 단계, 프로브 단계로 나뉨</li>
</ul>
<h4 id="빌드-단계--입력-테이블-중-하나를-기반으로-메모리-내-해시-테이블을-빌드하는-단계">빌드 단계 : 입력 테이블 중 하나를 기반으로 메모리 내 해시 테이블을 빌드하는 단계</h4>
<ul>
<li>바이트가 더 작은 테이블을 기반으로 해서 테이블을 빌드</li>
<li>조인에 사용되는 필드가 해시 테이블의 키로 사용됨</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/e86dc62d-f49e-4385-aba4-8a0bfa804f7d/image.png" alt=""></p>
<h4 id="프로브-단계--레코드-읽기를-시작하며-각-레코드에서-특정-값에-일치하는-레코드를-찾아서-결과값으로-반환하는-단계">프로브 단계 : 레코드 읽기를 시작하며, 각 레코드에서 특정 값에 일치하는 레코드를 찾아서 결과값으로 반환하는 단계</h4>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/80021588-2838-45bd-899a-38d5c76060ef/image.png" alt=""></p>
<p>이를 통해 각 테이블은 한 번씩만 읽게 되어 중첩해서 두 개의 테이블을 읽는 중첩 루프 조인보다 보통은 성능이 더 좋다. 참고로 사용 가능한 메모리양은 시스템 변수 join_buffer_size 에 의해 제어되며, 런타임 시에 조정할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 스터디 4회차 - (6)]]></title>
            <link>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-6</link>
            <guid>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-6</guid>
            <pubDate>Fri, 16 May 2025 15:41:48 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hi_rice/post/47222abe-15ca-438d-866d-e121578f4351/image.jpeg" alt=""></p>
<h2 id="46-조인의-종류">4.6 조인의 종류</h2>
<p>조인은 두 개 이상의 테이블을 묶어서 하나의 결과물을 만드는 것이다.</p>
<ul>
<li>MySQL : JOIN 쿼리</li>
<li>MongoDB : lookup 쿼리</li>
</ul>
<p>MongoDB의 lookup 연산은 관계형 데이터베이스 조인 연산보다 성능이 떨어지므로, 여러 테이블을 조인하는 작업이 많을 경우 관계형 데이터베이스 사용해야 한다.</p>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/9891a268-6054-49ae-b812-e2e100989caf/image.png" alt=""></p>
<h3 id="461-내부-조인">4.6.1 내부 조인</h3>
<p>내부 조인 (inner join) : 왼쪽 테이블과 오른쪽 테이블의 두 행이 모두 일치하는 행이 있는 부분만 표기
두 테이블 간에 교집합을 나타냄</p>
<pre><code>SELECT * FROM TableA A
INNER JOIN TableB B ON A.key = B.key</code></pre><h3 id="462-왼쪽-조인">4.6.2 왼쪽 조인</h3>
<p>왼쪽 조인 (left outer join) : 왼쪽 테이블의 모든 행이 결과 테이블에 표기
오른쪽 테이블에 일치하는 항목이 없으면 해당 값은 null 값이 됨</p>
<pre><code>SELECT * FROM TableA A
LEFT JOIN TableB B ON A.key = B.key</code></pre><h3 id="463-오른쪽-조인">4.6.3 오른쪽 조인</h3>
<p>오른쪽 조인 (right outer join) : 오른쪽 테이블의 모든 행이 결과 테이블에 표기
왼쪽 테이블에 일치하는 항목이 없으면 해당 값은 null 값이 됨</p>
<pre><code>SELECT * FROM TableA A
RIGHT JOIN TableB B ON A.key = B.key</code></pre><h3 id="464-합집합-조인">4.6.4 합집합 조인</h3>
<p>합집합 조인 (full outer join) : 두 개의 테이블을 기반으로 조인 조건에 만족하지 않는 행까지 모두 표기
일치하는 항목이 없으면 누락된 쪽에 null 값이 포함되어 출력</p>
<pre><code>SELECT * FROM TableA A
FULL OUTER JOIN TableB B ON A.key = B.key</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[CS 스터디 4회차 - (5)]]></title>
            <link>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-5</link>
            <guid>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-5</guid>
            <pubDate>Fri, 16 May 2025 15:35:51 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hi_rice/post/8d792246-8769-4a07-b548-a56f2618f00d/image.jpeg" alt=""></p>
<h2 id="45-인덱스">4.5 인덱스</h2>
<h3 id="451-인덱스의-필요성">4.5.1 인덱스의 필요성</h3>
<p>인덱스란 데이터를 빠르게 찾을 수 있는 하나의 장치를 말한다.  - 마치 책의 마지막 장의 &#39;찾아보기&#39;</p>
<h3 id="452-b-트리">4.5.2 B-트리</h3>
<p>인덱스는 보통 B-트리라는 자료 구조로 이루어져 있다.
이는 루트 노드, 리프 노드, 루트 노드와 리프 노드 사이의 브랜치 노드로 나뉜다.</p>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/ede3a0ff-2e5e-43b7-864c-f1dcbf86d9a9/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/743d3ba0-172e-4689-939e-f7d4647d4808/image.png" alt=""></p>
<p>인덱스가 효율적인 이유는 효율적인 단계를 거쳐 모든 요소에 접근할 수 있는 균형 잡인 트리 구조와 트리 깊이의 대수확장성 때문이다.</p>
<p>대수확장성 : 트리 깊이가 리프 노드 수에 비해 매우 느리게 성장하는 것</p>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/1b5aaa3f-9bab-40c3-aeae-60820bf99f96/image.png" alt=""></p>
<h3 id="453-인덱스-만드는-방법">4.5.3 인덱스 만드는 방법</h3>
<h3 id="mysql">MySQL</h3>
<p>MySQL의 경우 클러스터형 인덱스와 세컨더리 인덱스가 있다.
클러스터형 인덱스는 테이블당 하나를 설정할 수 있다. primary key 옵션으로 기본키를 만들면 클러스터형 인덱스를 생성할 수 있고, 기본키로 만들지 않고 unique not null 옵션을 붙이면 클러스터형 인덱스로 만들 수 있다.
세컨더리 인덱스는 보조 인덱스로 여러 개의 필드 값을 기반으로 쿼리를 많이 보낼 때 생성해야 하는 인덱스이다. create index... 명령어를 기반으로 만들면 세컨더리 인덱스를 만들 수 있다. 하나의 인덱스만 생성할 것이라면 클러스터형 인덱스를 만드는 것이 세컨더리 인덱스를 만드를 것보다 성능이 좋다.</p>
<h3 id="mongodb">MongoDB</h3>
<p>MongoDB의 경우 도큐먼트를 만들면 자동으로 ObjectID가 형성되며, 해당 키가 기본키로 설정된다. 그리고 세컨더리 키도 부가적으로 설정해서 기본키와 세컨더리 키를 같이 쓰는 복합 인덱스를 설정할 수 있다.</p>
<h3 id="454-인덱스-최적화-기법">4.5.4 인덱스 최적화 기법</h3>
<ol>
<li>인덱스는 비용이다.</li>
</ol>
<ul>
<li>인덱스는 두 번 탐색하도록 강요</li>
</ul>
<p>인덱스 리스트, 컬렉션 순으로 탐색하기 때문에 관련 읽기 비용이 듦
컬렉션이 수정되었을 때 인덱스도 수정되어야 한다.
따라서 쿼리에 있는 필드에 인덱스를 무작정 다 설정하는 것은 답이 아니다.</p>
<p>컬렉션에서 가져와야 하는 양이 많을수록 인덱스 사용이 비효율적이 된다.</p>
<ol start="2">
<li>항상 테스팅하라.</li>
</ol>
<ul>
<li>인덱스 최적화 기법은 서비스에서 사용하는 객체의 깊이, 테이블의 양 등에 따라 달라지므로 항상 테스팅이 필요하다.</li>
</ul>
<p>explain() 함수를 통해 인덱스를 만들고 쿼리를 보낸 이후에 테스팅을 하며 걸리는 시간 최소화해야 한다.</p>
<pre><code>EXPLAIN
SELECT * FROM t1
JOIN t2 ON t1.c1 = t2.c1</code></pre><ol start="3">
<li>복합 인덱스는 같음, 정렬, 다중 값, 카디널리티 순이다.</li>
</ol>
<ul>
<li>보통 여러 필드를 기반으로 조회를 할 때 복합 인덱스를 생성하는데, 이 인덱스 생성 순서에 따라 성능이 달라짐</li>
</ul>
<p>어떠한 값과 같음을 비교하는 ==이나 equal이라는 쿼리가 있다면 제일 먼저 인덱스로 설정
정렬에 쓰는 필드라면 그다음 인덱스로 설정
다중 값을 출력해야 하는 필드, 즉 쿼리 자체가 &gt;이거나 &lt; 등 많은 값을 출력해야 하는 쿼리에 쓰는 필드라면 나중에 인덱스 설정
유니크한 값의 정도 : 카디널리티. 이 카디널리티가 높은 순서를 기반으로 인덱스를 생성해야 한다. 예를 들어 age와 email이 있을 때, email이 더 높다. 즉 email이라는 필드에 대한 인덱스를 먼저 생성해야 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[서초 AI 칼리지 데이터분석] - (5)]]></title>
            <link>https://velog.io/@hi_rice/%EC%84%9C%EC%B4%88-AI-%EC%B9%BC%EB%A6%AC%EC%A7%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B6%84%EC%84%9D-5</link>
            <guid>https://velog.io/@hi_rice/%EC%84%9C%EC%B4%88-AI-%EC%B9%BC%EB%A6%AC%EC%A7%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B6%84%EC%84%9D-5</guid>
            <pubDate>Fri, 16 May 2025 04:46:16 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hi_rice/post/d18e4c5b-a17a-400b-bf1f-fad347644c74/image.png" alt=""></p>
<h2 id="pandas-데이터프레임-활용---1">Pandas 데이터프레임 활용 - (1)</h2>
<ol>
<li>Sample 데이터 불러오기</li>
<li>데이터프레임 조작하기</li>
<li>조건문 활용하여 데이터 조회하기</li>
<li>데이터 프레임 내 문자열 처리</li>
<li>그룹 연산 : groupby()</li>
</ol>
<h3 id="sample-data-불러오기">Sample Data 불러오기</h3>
<ul>
<li>Pandas 실습을 위해서 Seaborn 라이브러리에서 제공하는 데이터셋 사용</li>
<li>pip install seaborn : seaborn 라이브러리 설치</li>
<li>seaborn에서 load dataset을 활용하여 연습용 데이터 불러오기</li>
</ul>
<pre><code>import seaborn as sns   # Seaborn 라이브러리
print(sns.get_dataset_names())</code></pre><pre><code>iris = sns.load_dataset(&#39;iris&#39;)     # iris 라는 이름의 데이터셋 불러오기
iris.head()</code></pre><h3 id="dataframe-조작-">DataFrame 조작 +@</h3>
<ul>
<li>특정 열 제거하기 : drop</li>
<li>drop() 함수 내에 삭제하려는 column 이름이나 index를 작성</li>
<li>axis = 1 : 열을 제거 하는 경우 1, 행을 제거하는 경우 0으로 설정</li>
</ul>
<pre><code>print(&#39;Before : &#39;, iris.columns.tolist())
iris = iris.drop([&#39;petal_width&#39;],axis=1)    #petal_width 컬러 제거
print(&#39;After : &#39;, iris.columns.tolist())</code></pre><ul>
<li>특정 열/행의 합 구하기</li>
<li>sum() 함수를 활용해 특정 열/행 의 총합을 계산한다.</li>
<li>특정 열에 대한 정보만 얻거나 여러 열의 합을 구할 수도 있다.</li>
<li>Arguments</li>
<li>axis = 0 : 행(0) 또는 열(1) 중에서 계산을 할 축을 의미</li>
</ul>
<pre><code>iris.sum()      #iris 데이터의 모든 열마다 합을 계산</code></pre><ul>
<li>중복치 처리 : duplicated()</li>
<li>데이터 내에 존재하는 중복된 행 or 열 확인</li>
<li>duplicated() : 중복된 열들을 확인한다</li>
<li>sum() 함수와 함께 사용해 중복된 갯수를 얻을 수 있다</li>
</ul>
<pre><code>iris[&#39;species&#39;].duplicated().head()     #붓꽃의 종류가 중복되는지 확인</code></pre><ul>
<li>중복치 처리 : drop_duplicates()</li>
<li>데이터 내에 존재하는 중복된 행 or 열 제거</li>
<li>drop_duplicates(column_name_list) : 중복된 행/열을 제거한다</li>
<li>Arguments<ul>
<li>기준으로 하는 열들의 이름 리스트</li>
<li>keep : 중복된 것들 중, 남길 항목 선정 [&#39;first&#39;, &#39;last, False]</li>
</ul>
</li>
</ul>
<pre><code>iris.drop_duplicates([&#39;petal_length&#39;],keep=&#39;first&#39;).head()     # petal_length가 같은 행을 모두 제거 + 가장 먼저 등장한 행 남기기</code></pre><h3 id="자료형-변환">자료형 변환</h3>
<ul>
<li>특정 열의 자료형을 강제로 변경 : astype</li>
<li>pandas TrE&amp; : object, int64, float64, bool, datetime, category...</li>
<li>자료형의 효율성 차이가 있거나 자료형이 잘 못 지정된 경우 사용</li>
<li>df[변경대상컬럼].astype(변경할_데이터타입)</li>
</ul>
<pre><code>iris[&#39;sepal_width_str&#39;] = iris[&#39;sepal_width&#39;].astype(str)   # sepal_width 를 str으로 저장
print(iris[&#39;sepal_width_str&#39;])</code></pre><h3 id="indexing">Indexing</h3>
<ul>
<li>기본적인 조건문 외에 직접 행/ 선택 : loc &amp; iloc</li>
<li>index를 사용하여 직접 행이나 열을 선택할 수 있다.</li>
<li>loc : 조건문이나 label을 통해 행/열을 선택</li>
<li>iloc : index를 기반으로 행/열을 선택</li>
</ul>
<pre><code>iris.loc[10,&#39;species&#39;]      # 10이라는 index를 가지며, &#39;species&#39;를 column label로 가지는
iris.iloc[10,3]      # 10번 행 index와 column의 3번 index인 &#39;species&#39;를 불러옴
iris.iloc[:,3]      # 1column의 3번 index인 &#39;species&#39;를 모두 불러옴</code></pre><h3 id="문자열-처리">문자열 처리</h3>
<ul>
<li>공백 제거하기 : str.strip(), Istrip(), rstrip()</li>
<li>문자열 앞/ 뒤에 공백이 들어가 있는 경우 제거</li>
<li>strip : 앞/뒤 모두 공백 제거</li>
<li>1&amp;r+ strip() : 앞 또는 뒤의 공백만 제거</li>
<li>ex) : df[&#39;species&#39;] = df[&#39;species&#39;].str.strip()<pre><code>iris.sepal_width_str</code></pre>구분자로 문자열 나누기 : str.split(구분자)</li>
<li>구분자를 기준을 특정 컬럼을 여러 컬럼으로 나눈다</li>
<li>예를 들어&quot;<a href="mailto:abcd@gmail.com">abcd@gmail.com</a>&quot;을 &#39;@&#39;로 나눌 경우 &#39;abcd와 &#39;gmail.com&#39; 두 개의 컬럼 생성</li>
<li>split 후 strip을 사용하여 에러 방지 가능</li>
</ul>
<pre><code>iris.sepal_width_str.str.split(&#39;.&#39;)     # string화 한 sepal_width 를 .를 기준으로 나누기</code></pre><p>패턴 찾기</p>
<ul>
<li>str.startswith(pat): 문자열이 pat 으로 시작하는지 여부를 반환 (Bool)</li>
<li>str.endswith(pat): 문자열이 pat으로 끝나는지 여부를 반환 (Bool)</li>
<li>str.contains(pat) : 문자열이 pat을 포함하는지 여부를 반환 (Bool)</li>
<li>str.match(pat:regex) : 정규표현식인 pat을 만족하는지 여부를 반환</li>
</ul>
<pre><code>iris[iris.species.str.contains(&#39;ini&#39;)].head()   #ini를 포함하는 virginica만 불러오게 하는 코드</code></pre><h3 id="groupby">GroupBy</h3>
<ul>
<li>그룹지어 연산하기 : groupby() + agg()</li>
<li>groupby 이후 여러 연산/통계를 한번에 구하고 싶은 경우</li>
<li>agg() 함수를 한번 더 활용한다.</li>
<li>agg()의 인자로 리스트가 오는 경우 : 모든 컬럼에 대해 해당 연산을 모두 진행</li>
<li>agg()의 인자가 dict 인 경우 : 해당하는 컬럼마다 dict의 연산만 진행</li>
</ul>
<pre><code>iris.groupby(&#39;species&#39;).agg([&#39;mean&#39;,&#39;var&#39;])      # iris의 species에 따라 그룹을 짓고 mean &amp; var를 구함</code></pre><p>그룹지어 연산하기 : groupby() +agg()</p>
<ul>
<li>groupby 이후 여러 연산/통계를 한번에 구하고 싶은 경우</li>
<li>agg() 함수를 한번 더 활용한다.</li>
<li>agg()의 인자로 리스트가 오는 경우 : 모든 컬럼에 대해 해당 연산을 모두 진행</li>
<li>agg()의 인자가 dict 인 경우 : 해당하는 컬럼마다 dict의 연산만 진행</li>
</ul>
<pre><code>iris.groupby(&#39;species&#39;).agg({
    &#39;sepal_length&#39; : &#39;mean&#39;,
    &#39;petal_length&#39; : [&#39;var&#39;,&#39;sum&#39;]
})      # iris의 species에 따라 그룹을 짓고 mean &amp; var를 구함</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[서초 AI 칼리지 데이터분석] - (4)]]></title>
            <link>https://velog.io/@hi_rice/%EC%84%9C%EC%B4%88-AI-%EC%B9%BC%EB%A6%AC%EC%A7%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B6%84%EC%84%9D-4</link>
            <guid>https://velog.io/@hi_rice/%EC%84%9C%EC%B4%88-AI-%EC%B9%BC%EB%A6%AC%EC%A7%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B6%84%EC%84%9D-4</guid>
            <pubDate>Thu, 15 May 2025 17:45:41 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hi_rice/post/0f3fb31c-f7ff-45c1-8f8c-fb01b179b292/image.png" alt=""></p>
<h3 id="pandas-와-numpy">Pandas 와 Numpy</h3>
<ul>
<li>Numpy와 유사하게<ul>
<li>Pandas는 대용량 데이터를 다루기 편하다</li>
<li>여러 차원(1<em>N~ N</em>M)의 데이터를 다룰 수 있다.</li>
</ul>
</li>
<li>하지만,<ul>
<li>Numpy는 주로 숫자 정보를 다루는 용도로 사용됨</li>
<li>Pandas는 다양한 타입의 데이터를 처리하기에 더 용이함 각 특성들(Column)의 이름을 만들거나, 형태를 쉽게 변형할 수 있다.</li>
</ul>
</li>
</ul>
<h3 id="pandas-란">Pandas 란?</h3>
<p>Pandas는 Numpy와 같이 Python에서 주로 사용되는 데이터분석 라이브러리</p>
<ul>
<li><p>Tabular 데이터를 다루기에 용이함</p>
</li>
<li><p>데이터는 행과 열로 정리되어 하나의 객체 단위로 사용이 가능함</p>
<ul>
<li>시리즈 (Series)</li>
<li>데이터 프레임 (DataFrame)</li>
</ul>
</li>
<li><p>효율적이고 빠르게 대용량 데이터를 활용할 수 있음</p>
</li>
</ul>
<h3 id="import-pandas">Import Pandas</h3>
<ul>
<li><p>Pandas 설치</p>
<ul>
<li>Numpy와 유사하게 Anaconda를 설치 한 뒤</li>
<li>Python Pip을 사용하여 설치</li>
</ul>
</li>
<li><p>Pandas 라이브러리 불러오기</p>
<ul>
<li>import pandas</li>
<li>보통 Pandas 이름을 축약해서, &quot;import pandas as pd&quot; 로 사용</li>
</ul>
</li>
</ul>
<h3 id="series">Series</h3>
<ul>
<li>가장 기본적인 Pandas의 데이터 구조</li>
<li>Numpy의 Array와 유사한 형태</li>
<li>1차원 배열로 데이터를 저장한다</li>
<li>각 데이터의 행은 Index Number를 가지고 있다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/0bda52cb-0f79-40f4-9a57-56f7315d3ce6/image.png" alt=""></p>
<h3 id="series-생성">Series 생성</h3>
<ul>
<li><p>Series를 생성하기 위해서는 데이터가 필요 : (예시) [10,20,30]</p>
</li>
<li><p>pd.Series(data=None, Index=None)를 사용하여 생성</p>
</li>
<li><p>예시 1) scores = pd.Series([10,20,30])</p>
</li>
<li><p>예시 2) costs = pd.Series(range(0,1000,10)</p>
</li>
<li><p>예시 3) names = pd.Series([&quot;Tom&quot;,&quot;John&quot;, &quot;Jenny&quot;])</p>
</li>
</ul>
<pre><code>se1 = pd.Series()   # 비어있는 시리즈
se2 = pd.Series([1,2,3])    # 숫자 1,2,3 이 들어있는 시리즈
se3 = pd.Series([[1,2,3],[&#39;a&#39;,&#39;b&#39;,&#39;c&#39;]])    # 각 [1,2,3] 과 [&#39;a&#39;,&#39;b&#39;,&#39;c&#39;] 가 요소인 시리즈</code></pre><ul>
<li>시리즈 내부에 들어가는 Type<ul>
<li>하나의 타입만 넣는 경우, type은 하나로 결정됨 : Se1, se2
여러개의 타입을 섞는 경우, type =&#39;object : se3</li>
</ul>
</li>
</ul>
<h3 id="series-객체-활용">Series 객체 활용</h3>
<ul>
<li>Index 지정하기</li>
<li>pd.Series()의 두번째 인자로 index 값을 넣어 행 이름을 설정</li>
<li>ex) grades = pd.Series(data = [50,70,90], index=[&#39;Tom&#39;, &#39;John&#39;, &#39;Jenny&#39;])</li>
</ul>
<pre><code>grades =  pd.Series(data = [50,70,90], index=[&#39;Tom&#39;, &#39;John&#39;, &#39;Jenny&#39;])
grades</code></pre><h3 id="series-객체-활용-1">Series 객체 활용</h3>
<ul>
<li>통계 값 구하기<ul>
<li>Numpy와 동일하게 통계값을 리턴하는 함수 지원</li>
<li>describe(), mean(), std () 5</li>
<li>갯수, 평균, 쿼터별 값, median, 자료형 등의 정보를 돌려줌</li>
</ul>
</li>
</ul>
<pre><code>print(grades.mean())    # 평균 값
print(grades.std())     # 표준 편차
print(grades.count())   # 갯수
print(grades.describe())    # 전반적인 통계 정보</code></pre><h3 id="series-indexing">Series Indexing</h3>
<p>조건문(boolean)과 함께 사용하여 indexing</p>
<ul>
<li>원하는 조건을 만족하는 element만 가져온다</li>
<li>조건문 여러개를 연결하는 것도 가능</li>
</ul>
<pre><code>print(grades[grades&gt;60])    # 60보다 큰 점수만 필터링
print(grades[(grades&gt;60) &amp; (grades&lt;80)])    # 60보다 크고, 80보다 작은 점수만 필터링</code></pre></br>

<h3 id="dataframe">DataFrame</h3>
<ul>
<li>데이터 프레임은 2차원 배열</li>
<li>각 열(Column)에 각 Series들이 모여 하나의 객체 형성</li>
<li>각 행(Row)는 각 column에 해당하는 값들을 가짐</li>
<li>예) 2번 index Row는 각각 6,3,5의 과일을 가짐</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/6877d077-5e56-41b0-8347-0fd8959e40f6/image.png" alt=""></p>
<h3 id="dataframe의-생성">DataFrame의 생성</h3>
<ul>
<li>Series 생성 방법과 유사하게 pd.DataFrame(data)를 사용</li>
</ul>
<pre><code>df = pd.DataFrame([10,20,30]) # 데이터 프레임 생성
df</code></pre><p>2차원 배열로 저장되기에 Dictionary 형태로 입력 가능</p>
<ul>
<li>각 dictionary의 value들은 모두 같은 길이를 가져야 함.</li>
</ul>
<pre><code>df = pd.DataFrame({&#39;A&#39;:[1,2,3], &#39;B&#39;: [10,20,30], &#39;C&#39;:[100,200,300]})    # Dict 형태의 데이터 입력
df</code></pre><h3 id="dataframe의-속성들">DataFrame의 속성들</h3>
<ul>
<li>index : Series와 동일하게 행이나 열의 위치를 나타냄</li>
<li>columns : 열의 이름</li>
<li>shape : DataFrame의 모양</li>
<li>dtypes : column 들의 데이터 타입</li>
</ul>
<pre><code>print(&#39;Index : &#39;,df.index)     # index에 대한 정보
print(&#39;Columns : &#39;,df.columns)    # 모든 column의 이름
print(&#39;Shape : &#39;,df.shape)     # 데이터 프레임의 모양
print()
print(&#39;Types : &#39;,df.dtypes)    # 데이터들의 타입</code></pre><h3 id="dataframe-불러오기">DataFrame 불러오기</h3>
<ul>
<li>Pandas는 외부 데이터를 데이터 프레임화해서 불러올 수 있음</li>
<li>read_파일형식( 파일명 )의 함수를 사용</li>
<li>csv 파일의 경우, read_csV(파일명)</li>
</ul>
<pre><code>stock_df = pd.read_csv(&#39;stock-data.csv&#39;)    # 예시 데이터인 주식 데이터 불러오기
stock_df.dtypes</code></pre><h3 id="dataframe의-내장-함수들">DataFrame의 내장 함수들</h3>
<ul>
<li>head(N) : 데이터 프레임의 앞부분 N개를 미리 보여준다</li>
<li>tail(N) : 데이터 프레임의 끝부분 N개를 미리 보여준다</li>
<li>describe() : 데이터 프레임의 여러 통계 정보를 제공</li>
<li>info() : 데이터 프레임의 컬럼별 여러 정보를 제공</li>
</ul>
<pre><code>print(stock_df.head())
print(stock_df.tail())
print(stock_df.describe())
print(stock_df.info())
</code></pre><h3 id="dataframe-기본-인덱싱">DataFrame 기본 인덱싱</h3>
<ul>
<li>특정 컬럼만 필터링하기</li>
<li>데이터 프레임에 원하는 column 이름 리스트를 사용해 필터링</li>
<li>stock_df 의 [Date, Close, Start, High, Low, Volume] 중 앞 3개의 컬럼만 선택</li>
</ul>
<pre><code>stock_df[[&#39;Date&#39;,&#39;Close&#39;,&#39;Start&#39;]].head()      # 전체 컬럼 중, &#39;Date&#39;,&#39;Close&#39;,&#39;Start&#39; 만 선택</code></pre><h3 id="dataframe-내보내기">DataFrame 내보내기</h3>
<ul>
<li>Pandas 데이터프레임은 외부로, 원하는 포맷으로 저장이 가능</li>
<li>to_파일형식(파일 이름) : csv 파일의 경우, to_csV(파일명)</li>
<li>csv, json, xlsx 등 다양한 서식으로 내보내기 가능</li>
<li>stock_df 의 앞 세개 컬럼만 cSV로 내보내자!</li>
</ul>
<pre><code>new_stock = stock_df[[&#39;Date&#39;,&#39;Close&#39;,&#39;Start&#39;]]      # 전체 컬럼 중, &#39;Date&#39;,&#39;Close&#39;,&#39;Start&#39; 만 저장
new_stock.to_csv(&#39;stock-data-new.csv&#39;,index=False)  # 새로운 데이터프레임 csv로 추출</code></pre><h3 id="dataframe-합치기">DataFrame 합치기</h3>
<ul>
<li>여러 데이터 프레임을 합쳐야 한다면?</li>
</ul>
<pre><code>df1 = pd.DataFrame({
    &#39;A&#39;:[1,2,3],
    &#39;B&#39;: [10,20,30],
    &#39;C&#39;:[100,200,300]})

df2 = pd.DataFrame({
    &#39;A&#39;:[1,2,3,4,5,6],
    &#39;D&#39;:[&#39;a&#39;,&#39;b&#39;,&#39;c&#39;,&#39;d&#39;,&#39;e&#39;,&#39;f&#39;]})</code></pre><h3 id="dataframe-합치기---concat">DataFrame 합치기 - concat</h3>
<ul>
<li>여러 데이터 프레임을 이어붙여야 한다면?</li>
<li>pd.concat() 함수를 통해 여러 데이터 프레임을 이어붙일 수 있다!</li>
<li>공유하지 않는 column은 NaN으로 설정됨</li>
<li>Arguments<ul>
<li>ignore_index= False : 인덱스를 재설정 or not</li>
<li>axis = 0 : 세로(0), 가로(1) 방향 중 이어 붙일 곳 선택</li>
<li>join =&#39;outer : 행, 열이 맞지 않을 경우 skip or NaN</li>
</ul>
</li>
</ul>
<pre><code>pd.concat([df1,df2])    # df1과 df2 이어붙이기</code></pre><h3 id="dataframe-합치기--merge">DataFrame 합치기- merge</h3>
<ul>
<li>특정 key를 기준으로 여러 데이터 프레임을 합쳐야 한다면?</li>
<li>pd.merge() 함수를 사용해 합칠 수 있다!</li>
<li>Arguments<ul>
<li>on: 기준 Key가 될 Column을 설정</li>
<li>how=&#39;inner: 공통되지 않은 것들을 제거(&#39;inner), 그대로 두고 NaN으로 채우기(&#39;outer), &#39;left&#39;, &#39;right)</li>
</ul>
</li>
</ul>
<pre><code>pd.merge(df1,df2, on = &#39;A&#39;, how = &#39;inner&#39;)    # A 컬럼을 기준으로 df1과 df2 이어붙이기, how = inner</code></pre><pre><code>pd.merge(df1,df2, on = &#39;A&#39;, how = &#39;outer&#39;)    # A 컬럼을 기준으로 df1과 df2 이어붙이기, how = outer</code></pre><h3 id="dataframe-합치기--join">DataFrame 합치기 -join</h3>
<ul>
<li>Index를 기준으로 합쳐야 할때!</li>
<li>join() 함수를 사용 : 단, 붙이고자 하는 데이터 프레임에 사용<ul>
<li>ex. df.join(df2)</li>
</ul>
</li>
<li>Arguments<ul>
<li>how : 교집합(&#39;inner), 합집합(&#39;outer)</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 스터디 4회차 - (4)]]></title>
            <link>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-4</link>
            <guid>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-4</guid>
            <pubDate>Thu, 15 May 2025 08:17:04 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hi_rice/post/32207711-ac54-4fdb-a354-ce75c462bea7/image.jpeg" alt=""></p>
<h2 id="44-데이터베이스의-종류">4.4 데이터베이스의 종류</h2>
<h3 id="441-관계형-데이터베이스">4.4.1 관계형 데이터베이스</h3>
<p>관계형 데이터베이스는 행과 열을 가지는 표 형식 데이터를 저장하는 형태의 데이터베이스를 가리키며 SQL 이라는 언어를 써서 조작한다. MySQL, PostgreSQL, 오라클, SQL Server 등이 있다. </p>
<h3 id="mysql">MySQL</h3>
<p>MySQL은 대부분의 운영체제와 호환되며 현재 가장 많이 사용하는 데이터베이스이다.</p>
<ul>
<li>C, C++로 만들어짐</li>
<li>MyISAM 인덱스 압축 기술, B-트리 기반의 인덱스, 스레드 기반의 메모리 할당 시스템, 매우 빠른 조인, 최대 64개 인덱스 제공</li>
<li>대용량 데이터베이스를 위해 설계</li>
<li>롤백, 커밋, 이중 암포 지원 보안 등의 기능 제공</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/b50f26f6-dad1-4d7f-a681-2ed96415bd2c/image.png" alt=""></p>
<h3 id="스토리지-엔진--데이터베이스의-심장-역할">스토리지 엔진 : 데이터베이스의 심장 역할</h3>
<ul>
<li>모듈식 아키텍처로 쉽게 스토리지 엔진을 바꿀 수 있으며, 데이터 웨어 하우징, 트랜잭션 처리, 고가용성 처리에 강점</li>
<li>스토리지 엔진 위에 커넥터 API 및 서비스 계층을 통해 MySQL 데이터베이스와 쉽게 상호 작용</li>
<li>쿼리 캐시를 지원해 입력된 쿼리 문에 대한 전체 결과 집합을 저장하기 때문에 사용자가 작성한 쿼리가 캐시에 있는 쿼리와 동일하면 서버는 단순히 구문 분석, 최적화 및 실행을 건너뛰고 캐시의 출력만 표시</li>
</ul>
<h3 id="postgresql">PostgreSQL</h3>
<p>MySQL 다음으로 개발자들이 선호하는 데이터베이스 기술</p>
<ul>
<li>VACUUM : 디스크 조각이 차지하는 영역을 회수할 수 있음</li>
<li>최대 테이블 크기 : 32TB</li>
<li>SQL 뿐만 아니라 JSON 이용해 데이터에 접근 가능</li>
<li>지정 시간 복구 기능, 로킹, 접근 제어, 중첩된 트랜잭션, 백업 등</li>
</ul>
<h3 id="442-nosql-데이터베이스">4.4.2 NoSQL 데이터베이스</h3>
<p>NoSQL(Not Only SQL) 데이터베이스란 SQL을 사용하지 않는 데이터베이스를 말한다.</p>
<ul>
<li>전통적인 RDBMS와 다른 DBMS를 지칭하기 위한 용어로 데이터 저장에 고정된 테이블 스키마가 필요하지 않고 조인 연산 사용 불가능</li>
<li>수평적으로 확장 가능</li>
</ul>
<p>ex.MongoDB, redis 등</p>
<h3 id="mongodb">MongoDB</h3>
<p>JSON을 통해 데이터 접근 가능하며 Binary JSON 형태(BSON)로 데이터가 저장된다.</p>
<ul>
<li>와이어드타이거 엔진이 기본 스토리지 엔진으로 장착된 키-값 데이터 모델에서 확장된 도큐먼트 기반의 데이터베이스</li>
<li>확장성과 빅데이터 저장할 때 성능이 좋다</li>
<li>고가용성, 샤딩, 레플리카셋 지원</li>
<li>스키마를 정해 놓지 않고 데이터를 삽입할 수 있어 다양한 도메인의 데이터베이스를 기반으로 분석하거나 로깅 등을 구현할 때 강점이다.</li>
<li>도큐먼트를 생성할 때마다 다른 컬렉션에서 중복된 값을 지니기 힘든 유니크한 값인 ObjectID가 생성<ul>
<li>기본키로 유닉스 시간 기반의 타임스탬프(4바이트), 랜덤 값(5바이트), 카운터(3바이트)로 이루어짐</li>
</ul>
</li>
</ul>
<h3 id="redis">Redis</h3>
<p>인메모리 데이터베이스이자 키-값 데이터 모델 기반의 데이터베이스</p>
<ul>
<li>기본적인 데이터 타입 : 문자열(string)</li>
<li>최대 512MB까지 저장</li>
<li>이 외에도 셋(set), 해시(hash) 등 지원</li>
<li>pub/sub 기능을 통해 채팅 시스템, 다른 데이터베이스 앞단에 두어 사용하는 캐싱 계층, 단순한 키-값이 필요한 세션 정보 관리, 정렬된 셋(sorted set) 자료 구조를 이용한 실시한 순위표 서비스에 사용한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[서초 AI 칼리지 데이터분석] - (3)]]></title>
            <link>https://velog.io/@hi_rice/%EC%84%9C%EC%B4%88-AI-%EC%B9%BC%EB%A6%AC%EC%A7%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B6%84%EC%84%9D-3</link>
            <guid>https://velog.io/@hi_rice/%EC%84%9C%EC%B4%88-AI-%EC%B9%BC%EB%A6%AC%EC%A7%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B6%84%EC%84%9D-3</guid>
            <pubDate>Wed, 14 May 2025 17:36:08 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hi_rice/post/dc0804f4-4e60-4552-9891-32ca324cb9a3/image.webp" alt=""></p>
<h2 id="numpy-배열-마스킹">NumPy 배열 마스킹</h2>
<h3 id="마스킹">마스킹</h3>
<ul>
<li>외부의 병균이나 미세먼지로부터 막기 위해 마스크를 착용하는 것처럼 마스킹은 불필요한 것 들을 걸러내는 &#39;필터링&#39;과 유사한 기법이라고 생각하면 된다</li>
<li>넘파이 배열 마스킹은 마스크를 사용해서 배열의 특정 부분만 표시하는 것으로 보면 된다 마스크의 값들은 기본적으로 boolean 자료형으로 구성하며, 마스크의 원소값이 True면 대응 되는 원본 배열의 원소를 가져오고 False면 걸러내는 방식을 취한다.</li>
<li>대량의 데이터를 사용할 때 특정 데이터만을 추출하고자 하면 반복문보다는 이처럼 마스킹 기 법이 보다 효율적으로 작동될 수 있기에 필요하다</li>
<li>잇따라 오는 예제 코드를 통해 마스킹에 대해 더 알아보자</li>
</ul>
<pre><code>import numpy as np
my_first_mask = np.array([True, False, True, False])
my_second_mask = np.array([1, 0, 1, 0], dtype=bool)
print(my_first_mask)
print(my_second_mask) # my_first_mask와 동치
sample_arr = np.arange(12).reshape(4,3) # 4행 3열
print(sample_arr)
print(sample_arr[my_first_mask]) # (4,3) [(4,)] shape 성립; 마스크의 정보에 따라 0행과 2행만을 가져와 새로운 배열을 만들었다
print(sample_arr[my_second_mask]) # 위와 동치</code></pre><ul>
<li>넘파이 배열 마스킹은 마스크를 사용해서 배열의 특정 부분만 표시하는 것으로 보면 된다 </li>
<li>마스크는 ndarray 자료형으로 만들고 그 안의 원소값들은 boolean 자료형으로 구성한다 마스크와 대응되는 값이 True이면 가져오고 False이면 걸러내는 것이다 </li>
<li>사용법은 마스킹대상배열[마스크배열] 이처럼 기존의 인덱싱, 슬라이싱과 비슷하게 대괄호] 안에 마스크 배열을 넣어주어 마스킹하고자 하는 타겟 배열의 마스킹을 수행한다</li>
</ul>
<pre><code>mask1 = np.array([  [True, False, True],
                    [True, False, True],
                    [True, False, True],
                    [True, False, True] ])
print(sample_arr[mask1]) # (4,3) [(4,3)] shape 성립
print(type(sample_arr[mask1]))</code></pre><ul>
<li>마스크의 shape은 기존 배열의 shape의 차원 앞에서부터 대응이 되어야 한다; 기존 배열의 shape의 차원 앞에서부터 축의 길이가 동일해야 한다 (마스크 배열 사이즈 &lt;= 기존 배열 사이즈)</li>
<li>shape가 맞지 않은 경우 IndexError가 발생한다</li>
</ul>
<pre><code>mask2 = mask1.flatten()
print(mask2)
sample_arr[mask2]</code></pre><ul>
<li>ndarray 배열 객체에 ~를 접두하면 내부 원소들에 비트 연산 NOT을 수행한다 </li>
<li>이 점을 활용하여 마스크 배열 앞에 를 접두하여 마스크의 False 데이터만 추출할 수 있다</li>
</ul>
<pre><code>print(~np.array([True]))
print(~np.array([False]))
print(sample_arr[my_first_mask])
print(sample_arr[~my_first_mask]) # 올바른 False 마스킹
print(~sample_arr[my_first_mask]) # ~ 비트연산자 NOT</code></pre><ul>
<li>마스크 내부 원소값들을 int 자료형으로 구성할 수도 있다 </li>
<li>다만 작동 방식은 boo 자료형과 다르게 되는데, 원소값은 행의 인덱스 값으로 인식이 된다</li>
</ul>
<pre><code>int_mask = np.array([1, 0, 1, 0], dtype=int)
print(sample_arr) # 원래 배열
print(sample_arr[int_mask]) # 마스킹된 배열</code></pre><ul>
<li>그런데 매번 배열들에 대응되는 마스크 값을 일일히 지정할 수가 없다 (특히 배열의 크기가 커지면...)</li>
<li>배열들의 데이터를 필터링하는 기준이 있을테니 이를 활용하는 것이 좋은 방식이다</li>
<li>원본 배열에서 각종 연산을 거쳐서 이를 마스크 배열로써 활용해보자</li>
</ul>
<pre><code>print(sample_arr)
print(sample_arr[sample_arr&gt;=5]) # 비교 연산자
print(sample_arr[sample_arr%2==0]) # 나머지 연산자</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[서초 AI 칼리지 데이터분석] - (2)]]></title>
            <link>https://velog.io/@hi_rice/%EC%84%9C%EC%B4%88-AI-%EC%B9%BC%EB%A6%AC%EC%A7%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B6%84%EC%84%9D-2</link>
            <guid>https://velog.io/@hi_rice/%EC%84%9C%EC%B4%88-AI-%EC%B9%BC%EB%A6%AC%EC%A7%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B6%84%EC%84%9D-2</guid>
            <pubDate>Tue, 13 May 2025 18:17:10 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hi_rice/post/eef0a00a-6ed5-45d6-a547-0b0f493ade61/image.webp" alt=""></p>
<h2 id="numpy-배열-브로드캐스팅">NumPy 배열 브로드캐스팅</h2>
<h3 id="브로드캐스팅">브로드캐스팅</h3>
<ul>
<li>브로드캐스트(Broadcast)는 일반적으로 아는 라디오나 텔레비전 방송을 얘기하기도 하지만 &#39;흩뿌리다, 널리 퍼뜨리다&#39;라는 뜻도 가지고 있다</li>
<li>선형대수에서 행렬의 연산을 할 때 기본적으로 행렬의 크기(shape)가 동일해야 한다.</li>
<li>하지만 넘파이에서는 차원이나 크기가 다르더라도 일정한 조건을 충족하면 자동으로 확장하여 연산하게 되며 이를 브로드캐스팅이라고 한다
아래는 스칼라 브로드캐스팅 예제이다 (스칼라와 배열과의 연산은 브로드캐스팅을 통해 element-wise 연산을 수행한다)</li>
</ul>
<pre><code>import numpy as np
x = np.array([[1, 2],[3,4]]) # (2,2) 배열
print(x+5) # addition
print(x-3.) # subtraction
print(x*2) # product
print(x/2) # division
print(x//2) # floor division
print(x%2) # modulus
print(x**2) # power
print(np.sqrt(x)) # square root</code></pre><ul>
<li>브로드캐스팅을 수행함에 있어 준수해야 하는 특정한 규칙은 다음과 같다: 
연산하는 배열들의 뒤에서부터 대응하는 축의 길이가 동일 혹은 1이어야만 한다 스칼라 브로드캐스팅은 스칼라 자체의 축의 길이가 1이여서 신경을 쓰지 않아도 되지만 그 외는 아니다 위 조건이 충족되지 않으면 배열의 모양이 호환되지 않기에 ValueError 가 발생한다 연산 결과로 반환되는 배열은 입력 배열들의 차원 중에 가장 큰 크기로 반환된다.</li>
</ul>
<pre><code>arr1 = np.random.randn(30).reshape(2,3,5)
arr2 = np.random.randn(10).reshape(2,1,5)
print(arr1+arr2) # (2,3,5) 배열</code></pre><ul>
<li>연산하는 배열들의 뒤에서부터 대응하는 축의 길이가 동일 혹은 1이어야만 한다 연산 결과로 반환되는 배열은 입력 배열들의 차원 중에 가장 큰 크기로 반환된다.</li>
</ul>
<pre><code>arr1 = np.random.randn(30).reshape(2,3,5)
arr2 = np.random.randn(10).reshape(2,1,5)
arr3 = np.random.randn(15).reshape(1,3,5)
print(arr1+arr2+arr3)
print((arr1+arr2+arr3).shape)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[CS 스터디 4회차 - (3)]]></title>
            <link>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-3-gkvuo8m1</link>
            <guid>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-3-gkvuo8m1</guid>
            <pubDate>Tue, 13 May 2025 17:33:18 GMT</pubDate>
            <description><![CDATA[<h2 id="43-트랜잭션과-무결성">4.3 트랜잭션과 무결성</h2>
<h3 id="431-트랜잭션">4.3.1 트랜잭션</h3>
<p>트랜잭션은 데이터베이스에서 하나의 논리적 기능을 수행하기 위한 작업의 단위를 말하며 데이터베이스에 접근하는 방법은 쿼리이므로, 즉 여러 개의 쿼리들을 하나로 묶는 단위를 말한다.</p>
<ul>
<li>ACID 특징을 가짐 : 원자성, 일관성, 독립성, 지속성</li>
</ul>
<h3 id="원자성">원자성</h3>
<p>트랜잭션과 관련된 일이 모두 수행되었거나 되지 않았거나를 보장하는 특징 - &quot;all or nothing&quot;
트랜잭션이 커밋했는데, 문제가 발생하여 롤백하는 경우 그 이후에 모두 수행되지 않음을 보장한다.</p>
<p>트랜잭션 단위로 여러 로직들을 묶을 때 외부 API를 호출하는 것이 있으면 안 된다. 만약 있다면 롤백시에 해결법과 트랜잭션 전파를 신경써서 관리해야 한다.</p>
<h4 id="커밋과-롤백">커밋과 롤백</h4>
<ul>
<li>커밋 (commit) : 여러 쿼리가 성공적으로 처리되었다고 확정하는 명령어
변경된 내용이 모두 영구적으로 저장됨</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/6301e4d1-7a35-476e-8f4e-0b25386d1796/image.png" alt=""></p>
<ul>
<li>롤백 (rollback) : 트랜잭션으로 처리한 하나의 묶음 과정을 일어나기 전으로 돌리는 일(취소)</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/90251e5f-6c1f-46b8-9135-4cbb73b45490/image.png" alt=""></p>
<p>커밋과 롤벡 덕에 데이터의 무결성이 보장 가능하다.
데이터 변경 전에 변경 사항 쉽게 확인 가능하고, 해당 작업을 그룹화 할 수 있다.</p>
<h4 id="트랜잭션-전파">트랜잭션 전파</h4>
<ul>
<li>여러 트랜잭션 관련 메서드의 호출을 하나의 트랜잭션에 묶이도록 하는 것</li>
</ul>
<pre><code>@Service
@Transactional(readOnly = true)
public class MemberService{
    private final Member Repository memberRepository;

    public MemberService(MemberRepository memberRepository){
        this.memberRepository = memberRepository;
    }
}</code></pre><h3 id="일관성">일관성</h3>
<p>일관성이란 &#39;허용된 방식&#39;으로만 데이터를 변경해야 하는 것을 말한다.
데이터베이스에 기록된 모든 데이터는 여러 가지 조건, 규칙에 따라 유효함을 가져야 한다.</p>
<p>ex. 잔고 0원으로부터 500만원 송금 불가능</p>
<h3 id="격리성">격리성</h3>
<p>격리성이란 트랜잭션 수행 시 서로 끼어들지 못하는 것을 말한다.</p>
<p>복수의 병렬 트랜잭션은 서로 격리되어 마치 순차적으로 실행되는 것처럼 작동돼야 한다.
데이터베이스는 여러 사용자가 같은 데이터에 접근할 수 있어야 한다.
격리성은 여러 개의 격리 수준으로 나뉘어 격리성을 보장한다.</p>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/11801ba7-f290-429d-b02c-5ebb541a6280/image.png" alt=""></p>
<h4 id="격리-수준에-따라-발생하는-현상">격리 수준에 따라 발생하는 현상</h4>
<ul>
<li><p>팬텀 리드 (phantom read) : 한 트랜잭션 내에서 동일한 쿼리를 보냈을 때 해당 조회 결과가 다른 경우
동일한 쿼리에 다른 행이 선택될 수도 있음</p>
</li>
<li><p>반복 가능하지 않은 조회 (non-repeatable read) : 한 트랜잭션 내의 같은 행에 두 번 이상 조회 시, 그 값이 다른 경우
동일한 쿼리에 같은 행의 다른 값이 선택될 수도 있음</p>
</li>
<li><p>더티 리드 (dirty read) : 한 트랜잭션 실행 중에 아직 커밋되지 않은 행의 데이터를 읽을 수 있은 경우
다른 트랜잭션에 의해 수정되었지만 커밋되지 않은 상태일 수 있음</p>
</li>
</ul>
<h4 id="격리-수준">격리 수준</h4>
<ul>
<li><p>SERIALIZABLE : 트랜잭션을 순차적으로 진행
여러 트랜잭션이 동시에 같은 행 접근 불가
매우 엄격한 수준
교착상태가 일어날 확률 ⬆️
가장 성능이 떨어짐</p>
</li>
<li><p>REPEATABLE_READ
하나의 트랜잭션이 수정한 행을 다른 트랜잭션이 수정할 수 없도록 막아줌
다른 트랜잭션이 새로운 행을 추가하는 것은 막지 않음</p>
</li>
<li><p>READ_COMMITTED : 가장 많이 사용되는 격리 수준
커밋 완료된 데이터에 대해서만 조회를 허용
한 트랜잭션이 접근한 행을 다른 트랜잭션이 수정 가능
A가 수정하고 B가 다시 수정한 행을 A가 다시 읽을 때 다른 내용 발견 가능</p>
</li>
<li><p>READ_UNCOMMITTED : 가장 빠른 격리 수준
가장 낮은 격리 수준
하나의 트랜잭션이 커밋되기 이전에 다른 트랜잭션에 노출되는 문제가 있음
거대한 양의 데이터를 &#39;어림잡아&#39; 집계하는 데 사용하면 좋음</p>
</li>
</ul>
<h3 id="지속성">지속성</h3>
<p>지속성이란, 성공적으로 수행된 트랜잭션은 영원히 반영되어야 하는 것을 의미한다.
DB에 시스템 장애가 발생하도 원래 상태로 복구하는 회복 기능이 있어야 한다. 이를 위해 체크섬, 저널링, 롤백 등의 기능 제공한다.</p>
<ul>
<li>체크섬 : 중복 검사의 한 형태로, 오류 정정을 통해 무결성 보호</li>
<li>저널링 : 변경 사항을 반영(commit)하기 전에 로깅하는 것, 트랜잭션 등 변경 사항에 대한 로그를 남기는 것</li>
</ul>
<h3 id="무결성">무결성</h3>
<p>무결성이란 데이터의 정확성, 일관성, 유효성을 유지하는 것을 말한다.
무결성이 유지되어야 DB의 값과 그 값에 해당하는 현실 세계의 값이 일치한다고 신뢰할 수 있다.</p>
<table>
<thead>
<tr>
<th>이름</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>개체 무결성</td>
<td>기본키로 선택된 필드는 빈 값을 허용하지 않는다.</td>
</tr>
<tr>
<td>참조 무결성</td>
<td>서로 참조 관계에 있는 두 테이블의 데이터는 항상 일관된 값을 유지해야 한다.</td>
</tr>
<tr>
<td>고유 무결성</td>
<td>특정 속성에 대해 고유한 값을 가지도록 조건이 주어진 경우 그 속성 값은 모두 고유한 값을 가진다.</td>
</tr>
<tr>
<td>NULL 무결성</td>
<td>특정 속성 값에 NULL이 올 수 없다는 조건이 주어진 경우 그 속성 값은 NULL이 될 수 없다는 제약 조건이다.</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 스터디 4회차 - (2)]]></title>
            <link>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-2-1zgk5ca5</link>
            <guid>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-2-1zgk5ca5</guid>
            <pubDate>Tue, 13 May 2025 15:06:46 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hi_rice/post/8c0ca70f-7dc3-48d1-a0fa-6167d4e91b80/image.jpeg" alt=""></p>
<h2 id="42-erd와-정규화-과정">4.2 ERD와 정규화 과정</h2>
<p>ERD(Entity Relationship Diagram)는 데이터베이스를 구축할 때 가장 기초적인 뼈대 역할을 하며, 릴레이션 간의 관계들을 정의한 것이다. 만약 서비스를 구축한다면 가장 먼저 신경 써야 할 부분이다.</p>
<h3 id="421-erd의-중요성">4.2.1 ERD의 중요성</h3>
<ul>
<li>시스템의 요구 사항을 기반으로 작성됨</li>
<li>디버깅 또는 재설계가 필요한 경우에도 설계도 역할 담당</li>
<li>관계형 구조로 표현할 수 있는 데이터를 구성하는 데 유용함</li>
<li>비정형 데이터는 충분히 표현할 수 없음</li>
</ul>
<h3 id="422-예제로-배우는-erd">4.2.2 예제로 배우는 ERD</h3>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/7802f5e1-2117-4774-8253-b8aeba4f0948/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/4aea8fe9-4b82-4bee-a03a-d49b7c2b46d3/image.png" alt=""></p>
<h3 id="423-정규화-과정">4.2.3 정규화 과정</h3>
<p>정규화 과정이란 릴레이션 간의 잘못된 종속 관계로 인해 데이터베이스 이상 현상이 일어나서 이를 해결하거나, 저장 공간을 효율적으로 사용하기 위해 릴레이션을 여러 개로 분리하는 과정이다.</p>
<ul>
<li>정규형 원칙을 기반으로 정규형을 만들어가는 과정</li>
<li>정규화된 정도 : 정규형(NF, Normal Form)으로 표현</li>
<li>기본 정규형 : 제1 정규형, 제2 정규형, 제3 정규형, 보이스/코드 정규형</li>
<li>고급 정규형 : 제4 정규형, 제5 정규형</li>
<li>데이터베이스 이상 현상 : 회원이 한 개의 등급을 가져야 하는데 세 개의 등급을 갖거나, 삭제할 때 필요한 데이터가 같이 삭제되고 데이터를 삽입해야 하는데 하나의 필드값이 NULL이 되면 안되어서 삽입하기 어려운 현상</li>
</ul>
<blockquote>
<p>참고로, 정규화 과정을 거친다고 성능이 100% 좋아지는 것은 아니다.
테이블을 나누게 되면 어떠한 쿼리는 조인을 해야 하는 경우도 발생해서 오히려 느려질 수 있다.
서비스에 따라 정규화 또는 비정규화 과정을 진행해야 한다.</p>
</blockquote>
<h3 id="정규형-원칙">정규형 원칙</h3>
<p>같은 의미를 표현하는 릴레이션의 경우</p>
<ul>
<li>좀 더 좋은 구조로 만들어야 함</li>
<li>자료의 중복성은 감소해야 함</li>
<li>독립적인 관계는 별개의 릴레이션으로 표현해야 함</li>
<li>각각의 릴레이션은 독립적인 표현이 가능해야 함</li>
</ul>
<h3 id="제1정규형">제1정규형</h3>
<ul>
<li>릴레이션의 모든 도메인이 더 이상 분해될 수 없는 원자 값(atomic value)만으로 구성되어야 한다. 한 개의 기본키에 대해 두 개 이상의 값을 가지는 반복 집합이 있어서는 안 된다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/178fda4f-7b36-4445-b21c-a6ca0d690a1f/image.png" alt=""></p>
<h3 id="제2정규형">제2정규형</h3>
<ul>
<li>릴레이션이 제1 정규형이며 부분 함수의 종속성을 제거한 형태
기본키가 아닌 모든 속성이 기본키에 완전 함수 종속적이다.
릴레이션 분해시 동등한 릴레이션으로 분해해야 하고, 정보 손실이 발생하지 않는 무손실 분해가 돼야 한다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/fcb6c1e7-949a-42fa-93cb-8a438551f265/image.png" alt=""></p>
<h3 id="제3정규형">제3정규형</h3>
<ul>
<li>릴레이션이 제2 정규형이고 기본키가 아닌 모든 속성이 이행적 함수 종속(transitive FD)을 만족하지 않는 상태</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/e6f06481-fc01-440d-81d0-44bcd1678d4e/image.png" alt=""></p>
<ul>
<li>이행적 함수 종속 : A-&gt;B와 B-&gt;C가 존재하면 논리적으로 A-&gt;C가 성립하는데, 이때 집합C가 집합A에 이행적으로 함수 종속 되었다고 한다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/a9b8afcc-9b2e-4a45-9228-f64415f96f09/image.png" alt=""></p>
<h3 id="보이스코드-정규형">보이스/코드 정규형</h3>
<ul>
<li>릴레이션이 제3 정규형이고, 릴레이션의 함수 종속 관계에서 모든 결정자가 후보키인 상태.
결정자가 후보키가 아닌 함수 종속 관계를 제거한다.</li>
</ul>
<p>ex. 요구사항</p>
<ul>
<li>각 수강명에 대해 한 학생은 오직 한 강사의 강의만 수강</li>
<li>각 강사는 한 수강명만 담당</li>
<li>한 수강명은 여러 강사가 담당 가능</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/16e0e4e2-a282-4b22-9f69-d0bdfb9b8df6/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 스터디 4회차 - (1)]]></title>
            <link>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-1-6903stzr</link>
            <guid>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-4%ED%9A%8C%EC%B0%A8-1-6903stzr</guid>
            <pubDate>Tue, 13 May 2025 14:45:09 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hi_rice/post/11644c6c-d936-4727-a0d3-37ea0f5ea8d6/image.jpeg" alt=""></p>
<h2 id="41-데이터베이스의-기본">4.1 데이터베이스의 기본</h2>
<p>데이터베이스는 일정한 규칙 혹은 규약을 통해 구조화되어 저장되는 데이터 모음이다. 해당 데이터베이스를 제어, 관리하는 통합 시스템을 DBMS라고 하며, 데이터베이스 안에 있는 데이터들은 특정 DBMS마다 정의된 쿼리 언어를 통해 삽입, 삭제, 수정, 조회 등을 수행할 수 있다.
또한, 데이터베이스는 실시간 접근과 동시 공유가 가능하다.</p>
<h3 id="411-엔터티entity">4.1.1 엔터티(Entity)</h3>
<p>엔터티는 사람, 장소, 물건, 사건, 개념 등 여러 개의 속성을 지닌 명사를 의미한다. 예를 들어 회원이라는 엔터티가 있다고 한다면 회원은 이름, 아이디, 주소, 전화번호의 속성을 갖는다.</p>
<h4 id="약한-엔터티와-강한-엔터티">약한 엔터티와 강한 엔터티</h4>
<p>엔터티는 약한 엔터티와 강한 엔터티로 나뉜다. 예를 들어 A가 혼자서는 존재하지 못하고 B의 존재 여부에 따라 종속적이라면 A는 약한 엔터티이고 B는 강한 엔터티가 죈다.
방은 건물 안에만 존재하기 때문에 방은 약한 엔터티고 건물은 강한 엔터티라고 할 수 있다.</p>
<h3 id="412-릴레이션relation">4.1.2 릴레이션(Relation)</h3>
<p>릴레이션은 데이터베이스에서 정보를 구분하여 저장하는 기본 단위이다.
엔터티에 관한 데이터를 데이터베이스는 릴레이션 하나에 담아서 관리한다.
릴레이션은 관계형 데이터베이스에서는 테이블이라고 하고, NoSQL 데이터베이스에서는 컬렉션이라고 한다.</p>
<h4 id="테이블과-컬렉션">테이블과 컬렉션</h4>
<p>데이터베이스의 종류는 크게 관계형 데이터베이스와 NoSQL 데이터베이스로 나눌 수 있다. 대표적인 관계형 데이터베이스인 MySQL의 구조는 레코드-테이블-데이터베이스로 이루어져있고, NoSQL 데이터베이스인 MongoDB는 도큐먼트-컬렉션-데이터베이스로 이루어져있다.</p>
<h3 id="413-속성attribute">4.1.3 속성(attribute)</h3>
<p>속성은 릴레이션에서 관리하는 구체적이며 고유한 이름을 갖는 정보이다. 예를 들어 차라는 엔터티의 속성을 뽑아보면.
차 넘버, 바퀴 수, 차 색깔, 차종 등이 있다. 이 중에서 서비스의 요구 사항을 기반으로 관리해야 할 필요가 있는 속성들만 엔터티의 속성이 된다.</p>
<h3 id="414-도메인domain">4.1.4 도메인(domain)</h3>
<p>도메인이란 릴레이션에 포함된 각각의 속성들이 가질 수 있는 값의 집합을 말한다. 예를 들어 성별이라는 속성이 있다면 이 속성이 가질 수 있는 것은 {남, 여}라는 집합이 된다.</p>
<h3 id="415-필드와-레코드">4.1.5 필드와 레코드</h3>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/e833a5c0-c107-4cb9-9032-e3d8e10736b7/image.png" alt=""></p>
<p>회원이란 엔터티는 member라는 테이블로 속성인 이름, 아이디 등을 가지고 있으며 name, ID, address 등의 필드를 가진다. 그리고 이 테이블에 쌓이는 행 단위의 데이터를 레코드라고 한다. 또한, 레코드를 튜플이라고도 한다.</p>
<p>예를 들어 책이라는 엔터티를 정의하고 이를 기반으로 테이블을 만든다고 한다면.</p>
<ul>
<li>책의 아이디 : INT</li>
<li>책의 제목 : VARCHAR(255)</li>
<li>책의 저자 아이디 : INT</li>
<li>책의 출판년도 : VARCHAR(255)</li>
<li>책의 장르 : VARCHAR(255)</li>
<li>생성 일시 : DATETIME</li>
<li>업데이트 일시 : DATETIME</li>
</ul>
<p>이 테이블을 MySQL로 구현하면 다음과 같다.</p>
<pre><code>CREATE TABLE book(
    id INT NOT NULL AUTO_INCREMENT,
    title VARCHAR(255),
    author_id INT,
    publising_year VARCHAR(255),
    genre VARCHAR(255),
    created_at DATETIME,
    updated_at DATETIME,
    PRIMARY KEY (id)
);</code></pre><h3 id="필드-타입">필드 타입</h3>
<p>필드는 타입을 갖는다.</p>
<h3 id="숫자-타입">숫자 타입</h3>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/c94e39c6-d1ba-49cd-b982-9b36ee921753/image.png" alt=""></p>
<h3 id="날짜-타입">날짜 타입</h3>
<h4 id="date">DATE</h4>
<p>날짜 부분은 있지만 시간 부분은 없는 값에 사용된다. 지원되는 범위는 1000-01-01~9999-12-31이다. 3바이트의 용량을 가진다.</p>
<h4 id="datetime">DATETIME</h4>
<p>날짜 및 시간 부분을 모두 포함하는 값에 사용된다. 지원되는 범위는 1000-01-01 00:00:00에서 9999-12-31 23:59:59이다. 8파이트의 용량을 가진다.</p>
<h4 id="timestamp">TIMESTAMP</h4>
<p>날짜 및 시간 부분을 모두 포함하는 값에 사용된다. 1970-01-01 00:00:01에서 2038-01-19 03:14:07까지 지원한다. 4바이트의 용량을 가진다.</p>
<h3 id="문자-타입">문자 타입</h3>
<h4 id="char와-varchar">CHAR와 VARCHAR</h4>
<p>CHAR 또는 VARCHAR 모두 그 안에 수를 입력해서 몇 자까지 입력할지 정한다. 예를 들어 CHAR(30)이라면 최대 30글자까지 입력할 수 있다.
CHAR는 고정 길이 문자열이며 길이는 0에서 255 사이의 값을 가진다. 레코드를 저장할 때 무조건 선언한 길이 값으로 고정해서 저장된다. 예를 들어 CHAR(100)으로 선언한 후 10글자를 저장해도 100바이트로 저장되게 된다.
VARCHAR는 가변 길이 문자열이다. 길이는 0에서 65,535 사이의 값으로 지정할 수 있으며, 입력된 데이터에 따라 용량을 가변시켜 저장한다. 예를 들어 10글자의 이메일을 저장할 경우 10글자에 해당하는 바이트 + 길이기록용 1바이트로 저장하게 된다. VARCHAR(10000)으로 선언해도 같다.
그렇기 때문에 CHAR의 경우 유동적이지 않은 길이를 가진 데이터의 경우에 효율적이고 유동적인 길이를 가진 데이터는 VARCHAR로 저장하는 것이 좋다.</p>
<h4 id="text와-blob">TEXT와 BLOB</h4>
<p>TEXT는 큰 문자열 저장에 쓰며 주로 게시판의 본문을 저장할 때 쓴다.
BLOB은 이미지, 동영상 등 큰 데이터 저장에 쓴다. 그러나 보통은 아마존의 이미지 호스팅 서비스인 S3를 이용하는 등 서버에 파일을 올리고 파일에 관한 경로를 VARCHAR로 저장한다.</p>
<h4 id="enum과-set">ENUM과 SET</h4>
<p>ENUM은 ENUM(&#39;w-small&#39;, &#39;small&#39;, &#39;medium&#39;, &#39;large&#39;, &#39;x-large&#39;) 형태로 쓰이며, 이 중에서 하나만 선택하는 단일 선택만 가능하고 ENUM 리스트에 없는 잘못된 값을 삽입하면 빈 문자열이 대신 삽입된다. ENUM을 이용하면 x-small 등이 0,1 등으로 매핑되어 메모리를 적게 사용하는 이점을 얻는다. ENUM은 최대 65,535개의 요소들을 넣을 수 있다.
SET은 ENUM과 비슷하지만 여러 개의 데이터를 선택할 수 있고 비트 단위의 연산을 할 수 있으며 최대 64개의 요소를 집어넣을 수 있다는 점이 다르다.
참고로 ENUM이나 SET을 쓸 경우 공간적으로 이점을 볼 수 있지만 애플리케이션의 수정에 따라 데이터베이스의 ENUM이나 SET에서 정의한 목록을 수정해야 한다는 단점이 있다.</p>
<h3 id="416-관계">4.1.6 관계</h3>
<p>데이터베이스에 테이블은 하나만 있는 것이 아니다. 여러 개의 테이블이 있고 이러한 테이블은 서로의 관계가 정의되어 있다. 이러한 관계를 관계화살표로 나타낸다.</p>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/31c6a737-0da3-4849-ad64-2920f5296e88/image.png" alt=""></p>
<h4 id="11-관계">1:1 관계</h4>
<p>ex. 유저당 유저 이메일이 하나씩 있는 경우</p>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/7a0dbe0e-4519-4841-9e51-44b426cb4336/image.png" alt=""></p>
<h4 id="1n-관계">1:N 관계</h4>
<ul>
<li>한 개체가 다른 많은 개체를 포함하는 관계</li>
</ul>
<p>ex. 한 유저당 어러 개의 상품을 장바구니에 넣는 경우</p>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/b5a00450-c802-49fd-a124-5bd500172fd3/image.png" alt=""></p>
<h4 id="nm-관계">N:M 관계</h4>
<ul>
<li>테이블 두 개를 직접적으로 연결해서 구축 하지 않음</li>
<li>1:N, 1:M 라는 관계를 갖는 테이블 두 개로 나눠서 설정</li>
</ul>
<p>ex. 학생과 강의의 관계</p>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/5f09db56-251e-4d72-9dc0-081d22a91694/image.png" alt=""></p>
<h3 id="417-키">4.1.7 키</h3>
<p>테이블 간의 관계를 조금 더 명확하게 하고 테이블 자체의 인덱스를 위해 설정된 장치로 기본키, 외래키, 후보키, 슈퍼키, 대체키가 있다.</p>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/ad6cdf25-a607-4f03-80ba-7bc0abdff0a8/image.png" alt=""></p>
<ul>
<li>유일성 : 중복되는 값이 없음</li>
<li>최소성 : 필드를 조합하지 않고 최소 필드만 써서 키를 형성할 수 있음</li>
</ul>
<h4 id="기본키-pk-primary-key">기본키 (PK, Primary Key)</h4>
<ul>
<li>유일성과 최소성을 만족하는 키</li>
<li>자연키 또는 인조키 중 설정</li>
</ul>
<h4 id="자연키">자연키</h4>
<p>중복되지 않는 것을 &#39;자연스레&#39; 뽑다가 나오는 키 - 언젠가는 변하는 속성을 가짐</p>
<h4 id="인조키">인조키</h4>
<p>인위적으로 생성한 키 - 변하지 않음 -&gt; 보통 기본키로 사용</p>
<h4 id="외래키-fk-foreign-key">외래키 (FK, Foreign Key)</h4>
<ul>
<li>다른 테이블의 기본키를 그대로 참조하는 값</li>
<li>개체와의 관계를 식별하는 데 사용
<img src="https://velog.velcdn.com/images/hi_rice/post/d08080c7-48b5-4163-8490-f79144d8671e/image.png" alt=""></li>
</ul>
<h4 id="후보키-candidate-key">후보키 (candidate key)</h4>
<ul>
<li>기본키가 될 수 있는 후보들</li>
<li>유일성과 최소성을 동시에 만족하는 키</li>
</ul>
<h4 id="대체키-alternate-key">대체키 (alternate key)</h4>
<ul>
<li>후보키가 두 개 이상이 경우 기본키 이외의 남은 후보키들</li>
</ul>
<h4 id="슈퍼키-super-key">슈퍼키 (super key)</h4>
<ul>
<li>레코드를 유일하게 식별할 수 있는 유일성을 갖춘 키</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[서초 AI 칼리지 데이터분석] - (1)]]></title>
            <link>https://velog.io/@hi_rice/%EC%84%9C%EC%B4%88-AI-%EC%B9%BC%EB%A6%AC%EC%A7%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B6%84%EC%84%9D-1</link>
            <guid>https://velog.io/@hi_rice/%EC%84%9C%EC%B4%88-AI-%EC%B9%BC%EB%A6%AC%EC%A7%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B6%84%EC%84%9D-1</guid>
            <pubDate>Mon, 12 May 2025 17:55:14 GMT</pubDate>
            <description><![CDATA[<h3 id="m01---numpy-표준-데이터타입--numpy-배열">M01 - Numpy 표준 데이터타입 : Numpy 배열</h3>
<h3 id="numpy">NumPY</h3>
<ul>
<li>넘파이는 대표적인 파이썬 수치 및 행렬 계산용 외부 라이브러리다.</li>
<li>외부 라이브러리이기에 개발 중에 넘파이에서 제공하는 기능을 사용하고 싶으면 사용하기 전에 코드 상에서 import 해야 한다.</li>
</ul>
<pre><code>1 !pip install numpy # NumPy 라이브러리가 설치 되어 있지 않을때만.
2 import numpy as np # 개발자들 십중팔구 numpy는 np라는 별칭(alias)을 사용</code></pre><ul>
<li><p>1995년 Numeric이라는 이름으로 출시한 후, 2006년 NumPy로 명칭을 바꾸고 꾸준히 개선됨.</p>
</li>
<li><p>특히 복잡한 행렬 계산(선형대수)과 관련된 기능을 많이 제공하여 범용적으로 사용된다.</p>
</li>
<li><p>파이썬 모듈(라이브러리, 패키지)에는 버전을 확인할 수 있는 _<em>version_</em> 속성을 지니도록 권장하고 있으며 넘파이 역시 이를 갖고 있다.</p>
</li>
</ul>
<pre><code>1 print(np.__version__) # 넘파이 버전 확인</code></pre><ul>
<li>넘파이에서는 다차원 행렬 계산을 위해 ndarray(그리고 matrix) 자료형을 자체적으로 가지고 있다.</li>
</ul>
<pre><code>1 my_first_array = np.array([0, 0.5, 1]) # 리스트로부터 ndarray 객체 생성(float와 int의 혼합)
2 print(my_first_array)
3 print(type(my_first_array))
4 print(type(my_first_array[0])) # float64로의 변환
5 print(my_first_array.dtype) # 전체 원소의 자료형</code></pre><ul>
<li>넘파이에서는 자체적인 자료형을 가지고 있는데 float64, int64가 예시이다.</li>
<li>ndarray 객체 생성 시 원소들이 전부 숫자이지만 하나라도 float 값이 들어간다면 원소 전체가 float64 자료형으로 변환됨을 확인할 수 있다.</li>
</ul>
<h3 id="ndarray-넘파이-배열">ndarray (넘파이 배열)</h3>
<ul>
<li>ndarray 객체는 배열로 간주하면 행렬과 유사하고, 관련 연산들을 지원한다.<ul>
<li>배열의 덧셈: 덧셈 연산자 +, 배열의 뺄셈: 뺄셈 연산자 -</li>
<li>배열의 원소별(element-wise) 곱셈: 곱셈 연산자 *</li>
<li>배열 원소별 나눗셈, 몫 연산, 나머지 연산: 나눗셈 연산자 /, 몫 연산자 //, 나머지 연산자 %</li>
</ul>
</li>
</ul>
<pre><code>1 my_second_array = np.array((1, 1, 1)) # 튜플로부터 ndarray 객체 생성 (int만으로 구성)
2 print(my_second_array)
3 print(type(my_second_array))
4 print(type(my_second_array[0]))
5 print(my_first_array + my_second_array) # 배열 덧셈
6 print(my_first_array - my_second_array) # 배열 뺄셈
7 print(my_first_array * my_second_array) # 배열 원소별 곱셈
8 print(my_first_array / my_second_array) # 배열 원소별 나눗셈
9 print(my_first_array // my_second_array) # 배열 원소별 몫 연산
10 print(my_first_array % my_second_array) # 배열 원소별 나머지 연산</code></pre><ul>
<li>ndarray 객체는 배열로 간주하고 관련 연산들을 지원한다.<ul>
<li>배열의 곱셈(내적) : @ 또는 dot 메소드</li>
</ul>
</li>
</ul>
<pre><code>1 A = np.array([[1, 2], [3, 4]]) # (2,2) shape의 배열
2 B = np.array([[1, 1], [2, 2]])
3 print(A, &quot;A.shape:&quot;, A.shape, &quot;A.ndim:&quot;, A.ndim)
4 print(&quot;A.size:&quot;,A.size, &quot;len(A):&quot;, len(A), &quot;\n&quot;)
5 print(B, &quot;\n&quot;)
6 print(A*B, &quot;\n&quot;) # 배열 원소별 곱셈
7 print(A@B) # 배열의 곱 (1)
8 print(A.dot(B)) # 배열의 곱(2)
9 print(np.dot(A,B)) # 배열의 곱 (3)</code></pre><p>shape은 구체적인 배열의 모양을 알려주고 ndim은 총 자원 수를 알려준다. (len(A.shape) == A.ndim) size는 배열 내의 모든 원소 개수를 알려주고 배열에서 사용하는 len 함수는 가장 바깥 (혹은 첫) 차원에서의 값을 나타낸다.
(len(A) == A.shape[0])</p>
<h3 id="numpy의-메소드">NumPy의 메소드</h3>
<ul>
<li>넘파이에서 제공하는 여러 메소드(=클래스 함수) 중 몇개를 소개한다.</li>
<li>arange : range 내장 함수와 거의 동일한 기능을 제공한다. 지정된 범위에 따라 ndarray 객체를 생성한다.</li>
</ul>
<pre><code>1 print(np.arange(5)) # 0부터(디폴트) 5이전까지 1 간격(디폴트)
2 print(np.arange(1, 5)) # 1부터 5이전까지 1간격(디폴트)
3 print(np.arange(1, 5, 2)) # 1부터 5이전까지 2간격</code></pre><ul>
<li>linspace : 특정 범위의 수를 균등하게 나누고자 할 때 사용한다.
np.linspace(start, stop, count) 이처럼 세 개의 파라미터를 받으며 &#39;start부터 stop까지 count개 구간으로 나눈다&#39;를 의미한다.</li>
</ul>
<pre><code>1 print(np.linspace(1, 50), len(np.linspace(1, 50))) # 1부터 50까지 총 50개 구간(디폴트)
2 print(np.linspace(1, 10, 5) # 1부터 10까지 총 5개 구간</code></pre><ul>
<li>zeros : shape에 맞춰서 float64 타입의 0으로 채워진 ndarray 객체 생성</li>
<li>zeros_like : 주어진 시퀀스 객체와 동일한 shape으로 int64 타입의 0으로 채워진 ndarray 객체 생성</li>
</ul>
<pre><code>1 print(np.zeros(5)) # float64 자료형으로 0을 채움
2 print(np.zeros(5).dtype)
3 C = np.array([[1,2],[3,4],[5,6]])
4 print(np.zeros_like(C)) # 특정 시퀀스 객체와 같은 shape을 가지되 0으로 채우기
5 print(np.zeros_like(C).dtype) # zeros와는 다르게 int64 자요형으로 0을 채움
6 d = [1,2]
7 print(np.zeros_like(d))
8 e = (1, 2, 3)
9 print(np.zeros_like(e))</code></pre><ul>
<li>full : 주어진 shape와 값에 맞춰서 채워진 ndarray 객체 생성(zeros_like, ones_like의 일반화된 버전)</li>
</ul>
<pre><code>1 print(np.full((2,3),3))
2 print(np.full((2,3),3).dtype)
3 print(np.full(shape=(2,3),fill_value=3.))
4 print(np.full((2,3), 3.)dtype)</code></pre><ul>
<li>eye : 주어진 shape에 맞춰서 Identical matrix(단위행렬) 객체 생성(Identical의 &#39;I&#39; 발음에 본따서 명칭)</li>
</ul>
<pre><code>1 print(np.eye(3)) # (3,3)으로 단위행렬 객체 생성
2 print(np.eye(3)*3) # (3,3)으로 값이 3인 대각행렬 생성</code></pre><ul>
<li>random.randn : 표준정규분포로부터 주어진 shape에 맞춰 난수를 채운 ndarray 객체 생성</li>
</ul>
<pre><code>1 print(np.random.randn(3))
2 print(np.random.randn(3,3))
3 print(np.random.randn(2,2,2))</code></pre><p>표준정규분포란, 평균이 0이고 표준 편차가 1인 정규분포를 의미한다.</p>
<ul>
<li>ndarray 객체는 reshape 속성 혹은 reshape 메소드를 통해 shape을 변경할 수 있다.</li>
</ul>
<pre><code>1 my_array = np.arange(10)
2 my_new_array = my_array.reshape(2,5) # reshape 속성
3 my_new_array2 = np.reshape(my_array, (2,-1))
    # reshape 메소드 -1은 인터프리터가 자동으로 연산
4 print(my_new_array)
5 print(my_new_array2)</code></pre><ul>
<li>성립될 수 없는 shape으로 모양을 변형하려고 하면 에러가 발생한다.</li>
</ul>
<pre><code>1 my_array = np.arange(10)
2 my_new_array2 = my_array.reshape(3,-1)</code></pre><ul>
<li>ndarray 객체는 T 속성 혹은 transpose 메소드를 통해 치환(transpose)할 수 있다</li>
</ul>
<pre><code>1 print(my_new_array) # (2,5) shape
2 my_new_array = my_new_array.T
3 print(my_new_array) # (5,2) shape
4 my_new_array = np.transpose(my_new_array)
5 print(my_new_array) # (2,5) shape
6 my_3d _array = np.arange(8).reshape(2,2,2)
7 print(my_3d _array)
8 my_3d_array= my_3d_array.T # 2D가 아닐 경우에는?
-&gt; 항상 처음과 마지막 axis간의 치환이 이뤄진다
9 print(my_3d_array)</code></pre><ul>
<li>swapaxes 메소드는 특정 축들간의 변경도 가능하다 (transpose의 일반화된 버전)</li>
</ul>
<pre><code>1 my_3d_array = np.arange(8).reshape(2,2,2)
2 print(my_3d_array)
3 my_3d_array = np.swapaxes(my_3d_array, 0, 1)
    # 0번째와 1번째 축간의 교환
4 print(my_3d_array)</code></pre><ul>
<li>ndarray의 결합과 분리와 관련된 메소드들 몇 가지에 대해서 알아보자</li>
<li>결합 : hstack, vstack, stack, concatenate</li>
<li>분리: split</li>
<li>hstack: horizontal stack; 넘파이 배열을 수평으로 쌓는다</li>
</ul>
<pre><code>1 count_to_ten = np.arange(1,11)
2 count_to_twenty = np.hstack[count_to_ten,count_to_ten+10])
3 print(count_to_twenty)</code></pre><ul>
<li>vstack: vertical stack; 넘파이 배열을 수직으로 쌓는다</li>
</ul>
<pre><code>1 count_to_twenty = np.vstack([count_to_ten, count_to_ten+10))
2 print(count_to_twenty)</code></pre><ul>
<li>stack: hstack과 vstack의 일반화 버전; 새로운 축을 생성하여 그 방향 으로 넘파이 배열을 결합한다</li>
</ul>
<pre><code>1 a = np.arange(1,5).reshape(2,2)
2 print(a, &quot;ndim:&quot;, a.ndim, &quot;shape:&quot;, a.shape)
3 print(np.stack([a, a+4, a+8]), np.stack([a, a+4, a+8]).shape) # axis = 0
4 print(np.stack([a, a+4, a+8], axis=1), np.stack([a, a+4, a+8], axis=1).shape)
5 print(np.stack([a, a+4, a+8], axis=2), np.stack([a, a+4, a+8], axis=2).shape)</code></pre><ul>
<li>concatenate: stack과는 다르게 기존에 있던 축을 활용하여 배열을 연장하는 방식</li>
</ul>
<pre><code>1 a = np.arange(1,5).reshape(2,2)
2 print(a, &quot;ndim:&quot;, a.ndim, &quot;shape:&quot;, a.shape)
3 print(np.concatenate([a, a+4, a+8]), np.concatenate([a, a+4, a+8]).shape)
4 print(np.concatenate([a, a+4, a+8], axis=1), np.concatenate([a, a+4, a+8], axis=1).shape)
5 print(np.concatenate(a, 314, a18), axis=2) 축오류 발생</code></pre><ul>
<li>split: split은 넘파이 배열을 분리하는 메소드로 np.split(ary, indices_or_sections, axis) 방식을 취한다.</li>
<li>첫번째 인자인 ary는 원본 넘파이 배열이고 세번째 인자인 axis는 분리하는 축 방향을 의미한다. (0이 디폴트)</li>
<li>indices_or_sections에 해당하는 인수가 정수형 N이라면 분리되는 배열이 N개의 동일한 값을 가진다 (나눌 수 없다면 오류 발생) 혹은 정렬된(sorted) 1D 꼴이라면 배열의 요소값을 기준으로 값을 나눈다</li>
</ul>
<pre><code>1 x = np.arange(6)
2 print(np.split(x,2)) # 2등분
3 print(np.split(x,3)) # 3등분
4 print(np splik 4) # 6개 원소를 4등분할 수 없음 (오류)</code></pre><pre><code>1 x = np.arange(6)
2 print(np.split(x,(2,3))) # 인덱스 2와 3을 기준으로 분리
3 print(np.split(x,[2,4,5,91)) # 인덱스 2, 4, 5, 그리고 9를 기준으로 분리</code></pre><pre><code>1 x = np.arange(6).reshape(2,3)
2 print(x)
3 print(np.split(x, 2)) # axis=0
4 print(np.split(x, 3, axis=1))
5 print(np.spligx, 2.axis=1) # 3개 원소를 2등분 불가능 (오류)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[CS 스터디 3회차 - (4)]]></title>
            <link>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-3%ED%9A%8C%EC%B0%A8-4</link>
            <guid>https://velog.io/@hi_rice/CS-%EC%8A%A4%ED%84%B0%EB%94%94-3%ED%9A%8C%EC%B0%A8-4</guid>
            <pubDate>Thu, 08 May 2025 08:50:27 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hi_rice/post/b4f8d5f5-1cbd-494e-8ef3-898dc3ae3bc8/image.jpeg" alt=""></p>
<h2 id="34-cpu-스케줄링-알고리즘">3.4 CPU 스케줄링 알고리즘</h2>
<p>CPU 스케줄러는 CPU 스케줄링 알고리즘에 따라 프로세스에서 해야 하는 일을 스레드 단위로 CPU에 할당한다.</p>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/ae24333a-64ac-4fc1-bc98-8d0c5fd20fdd/image.png" alt=""></p>
<p>프로그램이 실행될 때는 CPU 스케줄링 알고리즘이 어떤 프로그램에 CPU 소유권을 줄 것인지 결정한다. 이 알고리즘은 CPU 이용률은 높게, 주어진 시간에 많은 일을 하게, 준비 큐에 있는 프로세스는 적게, 응답 시간은 짧게 설정하는 것을 목표로 한다.</p>
<h3 id="341-비선점형-방식">3.4.1 비선점형 방식</h3>
<p>비선점형 방식은 프로세스가 스스로 CPU 소유권을 포기하는 방식이며 강제로 프로세스를 중지하지 않는다. 따라서 컨텍스트 스위칭으로 인한 부하가 적다.</p>
<h3 id="fcfs">FCFS</h3>
<p>FCFS는 가장 먼저 온 것을 가장 먼저 처리하는 알고리즘이다. 길게 수행되는 프로세스 때문에 준비 큐에서 오래 기다리는 현상이 발생하는 단점이 있다.</p>
<h4 id="sjf">SJF</h4>
<p>SJF는 실행 시간이 가장 짧은 프로세스를 가장 먼저 실행하는 알고리즘이다. 긴 시간을 가진 프로세스가 실행되지 않는 현상이 일어나면 평균 대기 시간이 가장 짧다. 하지만 실제로는 실행 시간을 알 수 없기 때문에 과거의 실행했던 시간을 토대로 추측해서 사용한다.</p>
<h3 id="우선순위">우선순위</h3>
<p>기존 SJF 스케줄링의 경우 긴 시간을 가진 프로세스가 실행되지 않는 현상이 있었다.
우선순위는 이 단점을 오래된 작업일수록 우선순위를 높이는 방법을 사용해 보완한 알고리즘이다.</p>
<h3 id="342-선점형-방식">3.4.2 선점형 방식</h3>
<p>선점형 방식은 현대 운영체제가 쓰는 방식으로 지금 사용하고 있는 프로세스를 알고리즘에 의해 중단시켜 버리고 강제로 다른 프로세스에 CPU 소유권을 할당하는 방식을 말한다.</p>
<h3 id="라운드-로빈">라운드 로빈</h3>
<p>라운드 로빈은 현대 컴퓨터가 쓰는 선점형 알고리즘 스케줄링 방법으로 각 프로세스는 동일한 할당 시간을 주고 그 시간 안에 끝나지 않으면 다시 준비 큐의 뒤로 가는 알고리즘이다.
로드밸런서에서 트래픽 분산 알고리즘으로도 쓰인다.</p>
<h3 id="srf">SRF</h3>
<p>SJF는 중간에 실행 시간이 더 짧은 작업이 들어와도 기존 짧은 작업을 모두 수행하고 그 다음 짧은 작업을 이어나가는데, SRF는 중간에 더 짧은 작업이 들어오면 수행하던 프로세스를 중지하고 해당 프로세스를 수행하는 알고리즘이다.</p>
<h3 id="다단계-큐">다단계 큐</h3>
<p>다단계 큐는 우선순위에 따른 준비 큐를 여러 개 사용하고, 큐마다 라운드 로빈이나 FCFS 등 다른 스케줄링 알고리즘을 적용한 것을 말한다. 큐 간의 프로세스 이동이 안 되므로 스케줄링 부담이 적지만 유연성이 떨어지는 특징이 있다.</p>
<p><img src="https://velog.velcdn.com/images/hi_rice/post/f3875911-bb1e-4d3b-8c6c-c37d7e3d9ee1/image.png" alt=""></p>
]]></description>
        </item>
    </channel>
</rss>