<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>HAZEL</title>
    <link>https://hazel01.tistory.com/</link>
    <description>IT / STUDY 
</description>
    <language>ko</language>
    <pubDate>Wed, 8 Apr 2026 14:33:29 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Rmsid01</managingEditor>
    <image>
      <title>HAZEL</title>
      <url>https://tistory1.daumcdn.net/tistory/3899282/attach/ccc3c69f615d4eea9ad263f01accaf2a</url>
      <link>https://hazel01.tistory.com</link>
    </image>
    <item>
      <title>린분석 : PART 1. 눈가리고 아웅하지 말기</title>
      <link>https://hazel01.tistory.com/124</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;린분석 : &lt;b&gt;스타트업이 지향해야 하는 목표를 추적하기 위해서 알아야 하는 지표에 관한 내용&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;린분석을 읽고 정리한 내용입니다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;CHAPTER 1. 우리는 모두 거짓말쟁이&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직감은 영감을 준다. 직감은 중요하다. 단, 직감을 테스트할 필요는 있다. 직감이 실험이라면 데이터는 증거다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제품이나 기능을 구현한 후에 효과를 측정하고 거기에서 교훈을 얻은 다음 더 좋은 제품을 구축할 수 있게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경영학의 대가 피터 드러커는 &amp;ldquo;측정할 수 없는 것은 관리할 수 없다&amp;rdquo;라는 유명한 말을 남겼다.&lt;/p&gt;
&lt;h1&gt;CHAPTER 2. 다양한 지표&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분석의 본질은 사업에서 매우 중요한 지표를 추적하는 것이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;좋은 지표란 어떤 것인가&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;좋은 지표의 특징
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;좋은 지표는 상대적이다.지난 주보다 전환율이 증가했다&amp;rsquo; 가 &amp;lsquo;전환율이 2%이다&amp;rsquo; 보다 더 좋은 정보이다.&lt;/li&gt;
&lt;li&gt;: 시대별, 사용자 그룹별, 경쟁자별로 비교할 수 있으면 상황을 이해하는데 도움이된다.&lt;/li&gt;
&lt;li&gt;좋은 지표는 이해하기 쉽다.&lt;/li&gt;
&lt;li&gt;: 사람들이 지표를 기억하고 그 지표에 대해 대화를 나눌 수 없다면 데이터의 변화를 현실의 변화로 옮기기 어렵다.&lt;/li&gt;
&lt;li&gt;좋은 지표는 비율로 표현된다.&lt;/li&gt;
&lt;li&gt;: 비율은 행동에 반영하기 쉽다 / 비율은 비교의 속성이 있다. / 비율은 다소 대조적인 요소들이나 내재된 갈등이 있는 요소들을 비교하기 좋다.&lt;/li&gt;
&lt;li&gt;좋은 지표는 행동 방식을 바꾼다. ⭐&amp;nbsp;가장 중요한 지표 ⭐&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;올바른 지표를 선택하기 위해 염두해야할 5가지
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정성적 지표와 정량적 지표&lt;br /&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;정성적 지표들은 체계적인 실험이 아닌 관찰이나 경험에 바탕을 두며 실상을 보여주지만 비구조적이고 종합하기 힘들다. 정량적 지표는 숫자와 통계의 형태를 띠며 구체적인 수치를 제공하지만 정황 정보가 부족하다. &lt;br /&gt;&lt;b&gt;&lt;span&gt;정량적 데이터가 &amp;lsquo;무엇&amp;rsquo;과 &amp;lsquo;얼마나 많이&amp;rsquo;에 대한 답을 제공한다면 정성적 데이터는 &amp;lsquo;왜&amp;rsquo;에 대한 답을 제공한다.&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;허상지표와 실질지표&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;: 허상 지표로 잠깐동안 기분이 좋을 수 있지만 행동을 바꿀 수 없다. 실질 지표는 행동 방침을 선택할때 도움을 줌으로써 행동을 바꾸게 한다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;많은 사람들이 데이터 드라이븐으로 일한다고 하지만, 실행에 옮길 수 없는 데이터는 허상 지표이다.ex, 전체 가입자수 / 전체 활동사용자 수는 허상지표라고 볼 수 있으며 &amp;lsquo;활동사용자 비율&amp;rsquo;/ '특정 기간 동안 확보한 사용자 수' 은 흥미로운 실질 지표이다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;데이터는 정보를 제공해주고 방향을 제시해주며 사업 모델을 개선시키고 행동방침을 결정하는데 도움이 되어야 한다. 어떤 지표를 볼 때마다 스스로에게 &amp;ldquo; 이 정보로 내가 무엇을 할 수 있을까?&amp;rdquo; 를 물어보아라. 대답할 수 없다면 중요한 지표가 아니다. 그저 데이터의 늪에서 허우적대고 있을 뿐이다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;b&gt;주의할 허상 지표 8가지&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;1. 히트 수 : 히트 수 대신 사용자 수를 세야 한다. &lt;br /&gt;&lt;/span&gt;&lt;b&gt;2. 페이지뷰 : 온라인 광고처럼 페이지뷰가 중요한 사업 모델이 아니라면 페이지 뷰 대신 사용자 수를 세야 한다.&lt;br /&gt;&lt;/b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;3. 방문 수 : 한사람이 백번 방문하는 경우와 백사람이 한번 방문하는 경우를 구분하지 못하기 때문에 좋은 지표가 아니다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;4. 순수 방문자 수 : 홈페이지를 방문한 사람의 수를 알려줄 뿐, 이 방문자들이 웹사이트에서 무엇을 했는지 / 왜 이 웹사이트에 머무는 지 / 이 웹사이트를 떠나는지의 여부는 전혀 알려주지 않는다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;5. 팔로어/친구/좋아요의 수&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;6. 사이트에 머무른 시간/페이지 수 : 사업에 관련된 페이지가 아닌 전체 페이지에 대한 것 이며 좋은 지표가 아니다. ( 가령 불만을 토로하는 페이지에 오래 머문다면 ? )&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;7. 수집된 이메일 주소&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;8. 다운로드 횟수 : 실질적 가치로 이어지기 위해서는 활성화, 계정 생성 등 다른 것들을 측정해야한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;탐색지표와 보고지표&lt;br /&gt;: 탐색 지표는 추론에 기반을 두고 있으며 유리한 고지를 차지할 수 있도록 아직 알려지지 않은 내용을 찾는데 목적이 있다. 보고지표는 정상적이고 이상적인 경영 상황을 빠짐없이 알 수 있도록 만드는데 목적이 있다.&lt;br /&gt;&lt;br /&gt;  &lt;/span&gt;&lt;b&gt;도널드 럼즈펠드의 숨은 천재성&lt;br /&gt;&lt;/b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;1. 안다는 것을 아는것 : 사실이 여기에 해당. 틀릴 수 있기 때문에 데이터와 대조하면서 확인해야한다.&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;2. 모른다는 것을 아는것 : 보고를 통해 답할 수 있는 질문은 여기에 해당한다. 기준을 정하고 자동화 해야한다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;3. 안다는 것을 모르는 것 : 직관이 여기에 해당한다. 정량화해야 하고 유효성과 효율성을 향상시킬 방법을 알아야한다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;4. 모른다는 것을 모르는 것 : 탐색이 여기에 해당한다. 경쟁 우위와 흥미로운 깨달음은 여기에서 비롯된다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;분석은 이 네가지 정보에 대해서 모두 중요한 역할을 한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;선행 지표와 후행 지표&lt;br /&gt;: 선행 지표는 미래를 예측할 수 있게 도와주고 후행 지표는 과거를 설명해준다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;두 가지 지표 모두 유용하지만 사용 목적이 다르다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;상관 지표와 인과 지표&lt;br /&gt;: 상관관계만으로 만족 해야 할 때도 있지만, 인과관계를 찾으려 항상 노력해야한다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;: 두 지표 값이 함께 움직이면 이 두 지표 사이에는 상관관계가 있다고 본다. 반면에 한 지표가 다른 지표를 변하게 하면 이 두 지표 사이에는 인과관계가 있다고 본다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분석가들은 사업을 이끄는 특정 지표를 분석하는데, 이것을 핵심 성과 지표 ( KPI : Key Performance Indicators) 라고 부른다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;목표 수정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 결정한 목표치는 확고 불변한 목표가 아니라 가변적인 목표다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러분의 가정과 사용자의 실제 행동은 크게 다를 수 있다. 이럴 때는 타당성을 입증할 수만 있다면 상황에 맞게 목표를 수정하는 것이 합리적이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;고객 세분화, 코호트, A/B 테스트, 다분량 분석&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트는 린분석의 핵심이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트란, 시장 세분화 / 코호트 분석/ AB 테스트를 통해 두가지를 서로 비교하는 것이다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 고객 세분화&lt;br /&gt;인구통계학적 정보에 따라 세분화할 수도있고 구매 패턴에 따라 고객군을 나눌 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고객 세분화(segmentation) 은 모든 산업과 모든 형태의 마케팅에 도움이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고객군이란, 공통의 특징을 공유하는 집단이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 코호트 분석 ( 종단적 연구 )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코호트 분석은 시간을 두고 비슷한 그룹을 비교하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코호트 분석은 스타트업 비즈니스에 중요하다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;전체고객&lt;/td&gt;
&lt;td&gt;1,000&lt;/td&gt;
&lt;td&gt;2,000&lt;/td&gt;
&lt;td&gt;3,000&lt;/td&gt;
&lt;td&gt;4,000&lt;/td&gt;
&lt;td&gt;5,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;고객당 평균 매출&lt;/td&gt;
&lt;td&gt;$5.00&lt;/td&gt;
&lt;td&gt;$4.50&lt;/td&gt;
&lt;td&gt;$4.33&lt;/td&gt;
&lt;td&gt;$4.25&lt;/td&gt;
&lt;td&gt;$4.50&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 표를 보고 사실 상황이 좋아지고 있는지, 나빠지고 있는지 알기 어렵다.&lt;br /&gt;최근에 가입한 고객과 이전에 가입한 고객들을 비교하지 않았고, 완전 신규고객의 구매액과 기존 고객의 구매액을 구별하지도 않았기 때문이다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;신규사용자&lt;/td&gt;
&lt;td&gt;1,000&lt;/td&gt;
&lt;td&gt;1,000&lt;/td&gt;
&lt;td&gt;1,000&lt;/td&gt;
&lt;td&gt;1,000&lt;/td&gt;
&lt;td&gt;1,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;전체 사용자&lt;/td&gt;
&lt;td&gt;1,000&lt;/td&gt;
&lt;td&gt;2,000&lt;/td&gt;
&lt;td&gt;3,000&lt;/td&gt;
&lt;td&gt;4,000&lt;/td&gt;
&lt;td&gt;5,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1개월&lt;/td&gt;
&lt;td&gt;$5.00&lt;/td&gt;
&lt;td&gt;$3.00&lt;/td&gt;
&lt;td&gt;$2.00&lt;/td&gt;
&lt;td&gt;$1.00&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2개월&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;$6.00&lt;/td&gt;
&lt;td&gt;$4.00&lt;/td&gt;
&lt;td&gt;$2.00&lt;/td&gt;
&lt;td&gt;$1.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3개월&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;$7.00&lt;/td&gt;
&lt;td&gt;$6.00&lt;/td&gt;
&lt;td&gt;$5.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4개월&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;$8.00&lt;/td&gt;
&lt;td&gt;$7.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5개월&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;$9.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코호트 분석을 진행해보면 시간이 지날 수록 가입한 고객들의 첫달 구매액의 거의 두배에 달한다. ( 신규회원에게는 강력한 앱인것 같다. ! )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 표처럼 가입한 달에 대한 코호트 분석 뿐만 아니라 사용자 경험에 따라 데이터를 나열 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex, 쇼핑몰 사용 개월 수를 기준으로 코호트 분석을 할 수 있다. ( 위의 표와 결론은 같아 보인다. )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코호트 분석을 통해, 첫달 구매액은 시간이 흘러감에 따라 점점 증가하며&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rsquo;첫 달 이후 구매액의 감소폭&amp;rsquo;에 대해 주의를 기울여야한다는 것을 확인 할 수있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. A/B 테스트와 다변량 테스트 ( 횡단적 연구 )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 테스트 대상인 그룹들에게 동시에 서로 다른 경험을 하게 하는 조사&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트래픽이 작은 경우에는 빠르게 실험을 할 수없다. 그러나 우리는 다양한 실험을 하고 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 &amp;lsquo;다변량 테스트&amp;rsquo;를 하고 싶다. 이러한 테스트를 하기 위해서는 &amp;lsquo;다변량 분석&amp;rsquo;이라는 기법을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다변량 분석에서는 많은 요소중 어떤 것이 핵심 지표의 개선과 강한 상관관계가 있는지 알아보기 위해 결과에 대해 통계적 분석을 실시한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 린 분석에 기반을 둔 스타트업의 생애주기&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;고객 유지율, 매출, 고객 활동 같이 개선할 KPI를 선택하되, 사업 단계와 사업 모델을 고려하여 가장 근본적인 사업상의 위험을 반영하는 KPI를 선택하라&lt;/li&gt;
&lt;li&gt;사업 모델을 바탕으로 그 KPI에 대해 기준을 정하라&lt;/li&gt;
&lt;li&gt;KPI를 개선시킬 방법을 파악하라
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;데이터가 없다면,&lt;/b&gt; 브레인 스토밍, 남의 아이디어 훔치기, 사용자 피드백 등&lt;/li&gt;
&lt;li&gt;&lt;b&gt;데이터가 있다면,&lt;/b&gt; 구매/회원가입/공유/기여/매출 창출 등을 통해 &amp;lsquo;좋은 방문자, 사용자,고객&amp;rsquo;을 찾아내라
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 &amp;lsquo;좋은&amp;rsquo; 사용자들의 공통점은 무엇인가?&lt;/li&gt;
&lt;li&gt;개선하고자 하는 KPI와 상관관계가 있으면서 &amp;lsquo;좋은&amp;rsquo; 사용자들이 공유하는 특징을 찾아라&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;액션
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;용감하다면,&lt;/b&gt; 이 공통된 특징을 대상으로 사업을 수정하라 ( 제품, 시장, 가격 정책 등)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;신중하다면,&lt;/b&gt; A/B 테스트 또는 다변량 테스트를 설계하라 &amp;rarr; 성공적인 솔류션을 구현하라&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;변화가 KPI에 미친 영향을 측정하라. 이 변화를 경험 사용자들의 코호트를 분석하라.&lt;/li&gt;
&lt;li&gt;KPI가 기준을 충족시켰는가?
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;NO 라면,&lt;/b&gt; 다시 시도하라 / 고객과 이야기를 나누고 새 기준을 정하라 / 방향을 전환하거나 포기하라.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;YES 라면,&lt;/b&gt; 다시 a 부터 새롭게 시작하라&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;CHAPTER 3. 어떤 일을 할 것인가&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;린 캔버스&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;린 캔버스란,&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행에 옮길 수 있는 한 페이지 짜리 사업 계획이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사업이 진행됨에 따라 내용도 계속 바뀌게된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전통적인 사업계획서와 달리 린캔버스는 지속적으로 이용하고 업데이트 해야한다. &amp;lsquo;살아 숨쉬는&amp;rsquo;계획서이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 장의 종이 위에 그려진 아홉 칸의 상자로 구성되어 있으며 사업의 가장 중요한 요소를 한눈에 살펴 볼 수 있게 설계 되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 린 캔버스의 구체적인 설명&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제 : 사람들이 불편함을 느끼는 진짜 문제점을 찾았는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고객군 : 목표 시장을 알고 있는가? 고객군을 구별해서 각각에 맞는 메시지를 전달할 방법을 알고 있는가 ?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고유의 가치 제안 : 여러분의 제품이 왜 더 나은지 또는 어떻게 다른지 명료하고 독특하며 기억에 남는 방법으로 설명할 수 있는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;솔루션 : 문제를 적절한 방식으로 해결할 수 있는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;채널 : 고객에게 제품이나 서비스를 어떻게 전달하고 매출을 발생시킬 것인가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수익원 : 수익이 어디에서 발생하는가? 일회성인가 반복적으로 발생하는가? 수익이 직접적으로 발생하는가 아니면 간접적으로 발생하는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비용구조 : 사업 운영에 필요한 직/간접적인 비용은 무엇인가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심 지표 : 사업이 잘되고 있는지 알기위해 어떤 숫자들을 추적해야 하는지 알고있는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경쟁우위 : 여러분의 노력이 경쟁자보다 더 좋은 결과를 내도록 만드는 &amp;lsquo;증폭기&amp;rsquo;는 무엇인가?&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;무슨 일을 해야하는가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;린 캔버스 외에 인간적으로 고려할 것이 있다. &amp;lsquo;여러분은 과연 그 일을 하고 싶은가?&amp;rsquo;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;창업가로서 성공하려면 (제품에 대한) 수요와 (제품을 만들 수 있는) 능력, (그런 제품을 만들고자하는) 욕구가 만나는 지점을 찾아야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같은 세가지 기준을 가지고 사업을 시작할 때 평가해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 내가 하고 싶은 이일을 잘 할 수 있는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 이 일을 좋아하는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 이 일로 돈을 버는가&lt;/p&gt;
&lt;h1&gt;CHAPTER 4. 데이터 주도적 접근법과 데이터를 참고하는 접근법&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;데이터를 분석할 때 피해야할 10가지 함정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 데이터에 결점이 없다고 가정하는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 표준화 하지 않는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 인기 있는 결혼식 장소를 얻기 이해 비행기를 타고온 사람의 수를 셀 수 있지만, 이때 전체 항공 승객수를 고려하지 않으면 &amp;lsquo;그저 비행기를&amp;nbsp; &amp;nbsp;이용하는 방문객 수&amp;rsquo;가 많은 도시들의 목록이 될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 열외의 사용자들을 배제하는 것 : 하루에 첫번이상 방문하는 사람은 열혈 팬일 수도있지만 검색 봇일 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 열외의 사용자들을 포함시키는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. 계절적 변동을 무시하는 것&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6. 성장을 평가할 때 전체 규모를 무시하는 것&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 사업을 막 시작할때 가족이 회원 가입만 해줘도 사용자 수는 2배가 증가할 수있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;7. 지나치게 많아 의미를 잃은 데이터&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 대시보드가 있어도 어떤 데이터를 봐야할지 모르면 아무 소용이 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8. 거짓 경보를 울리는 지표&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 자주 경보가 울리면 결국 여러분은 경보를 무시하게 될것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;9. 직접 수집한 데이터만 인정하는 배타적 태도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;10.잡음에 초점을 두는 것&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 인간의 속성은 패턴이 없는데도 패턴을 발견하도록 되어있다고 경고한다. 허상 지표는 무시하고 한 발 물러서서 더 큰 그림을 볼 줄 알아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DATA  ANALYSIS/Analysis</category>
      <category>데이터분석</category>
      <category>린분석</category>
      <category>지표</category>
      <author>Rmsid01</author>
      <guid isPermaLink="true">https://hazel01.tistory.com/124</guid>
      <comments>https://hazel01.tistory.com/124#entry124comment</comments>
      <pubDate>Sun, 27 Nov 2022 21:48:17 +0900</pubDate>
    </item>
    <item>
      <title>데이터리안 세미나 후기 : 데이터 실험 문화의 핵심 : A/B 테스트</title>
      <link>https://hazel01.tistory.com/123</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;세미나 주제 : 데이터 실험 문화의 핵심 : A/B 테스트&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;주최 : 월간 데이터리안&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;일시 : 2022.11.08 화 7시-9시&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;세미나 자료 ( 아래 이미지 출처 ) :&amp;nbsp;&lt;a href=&quot;https://www.datarian.io/blog/slide-webinar-nov&quot;&gt;https://www.datarian.io/blog/slide-webinar-nov&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;a href=&quot;https://medium.com/daangn/%EC%A7%81%EA%B4%80%EB%A7%8C-%EB%AF%BF%EA%B3%A0-%EA%B9%8C%EB%B6%88%EC%97%88%EB%8B%A4%EA%B0%80-%EB%A7%9D%ED%95%9C-pm%EC%9D%98-%EC%82%AC%EC%97%B0-61946dc969eb&quot;&gt;당근마켓 기술 블로그&lt;/a&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;lt;목차&amp;gt;&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;직관만 믿고 까물었다가 망한 PM의 사연&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;알아두면 쓸데있는 잡다한 A/B테스트 이야기&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;&lt;b&gt;1. 직관만 믿고 까물었다가 망한 PM의 사연&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고 :&amp;nbsp;&lt;a href=&quot;https://medium.com/daangn/%EC%A7%81%EA%B4%80%EB%A7%8C-%EB%AF%BF%EA%B3%A0-%EA%B9%8C%EB%B6%88%EC%97%88%EB%8B%A4%EA%B0%80-%EB%A7%9D%ED%95%9C-pm%EC%9D%98-%EC%82%AC%EC%97%B0-61946dc969eb&quot;&gt;당근마켓 기술 블로그&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;A/B 테스트 없이 '키워드 알림 등록 버튼을 변경하는 기획 진행&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당근마켓 ( 중고거래 특성상 ) 원하는 매물을 찾기까지 유저가 많은 탐색을 하는 특성을 가지고 있으며, 일반 유저들이 글을 쓰기 때문에 제목 또한 불친절합니다.&amp;nbsp;그래서 검색관점에서 난이도가 높은 도메인입니다.&amp;nbsp; 해당 PM의 경우 검색을 쉽게 하기 위해서 UI를 같이 개선하기 위해 키워드 알람 버튼이 있는 위치로 필터를 옮기는 작업을 하기로 하였습니다.&amp;nbsp; 그리고&amp;nbsp;&lt;b&gt;키워드 알림 등록 버튼은 아래로 변경하였습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론은 '키워드 알람수가 큰폭으로 하락' 하였습니다. 뿐만 아니라 '관심버튼 클릭' '채팅' 까지 하락하게 되었습니다.&amp;nbsp;추가 분석을 진행 한 결과, 안드로이드 보다 iOS에서 큰폭으로 떨어진 것을 확인 할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 원인 분석으로 안드로이드가 하단 네비게이션이 존재하여 시선이 아래로 갈 수 있지만, iOS의 경우는 시선이 아래로 가지 않기 때문에 유저들이 인지하지 못한것으로 해석하였습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;전사에 실수를 공유하고 수습 진행&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연사의 경우 실패했을때 숨기고 싶었으나, 넷플릭스의 공유하는 문화를 담은 책인 '규칙없음' 을 보고 인상깊었으며앞으로 나아가기 위해서는 실수를 공유하고 수습하는게 중요하다고 판단하였다고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;( 전사의 반응은 걱정과 다르게 공유해주어 고맙다는 피드백을 받았다고 합니다. )&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;실험과 결과 그리고 느낀점..&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대조군 대비 실험군C 의 키워드 알림 등록 전환율은 171.4% 높았으며, 처음 배포했던 B안이 제일 좋지 않은 전환율을 가지고 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연사는 해당 경험을 통해서 &quot;실패했을 때 빠르게 인정하고 적극적으로 공유하며 대응한 것이 좋은 선택이었어요. 그리고 그렇게 했을 때 신뢰하고 격려해 주는 좋은 동료들과 함께 하고 있다는 것도 한번 더 느낄 수 있었어요&quot; 라고 말했습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;직관과 데이터 사이&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 분석가 출신이라 '데이터가 중요하지' 라고만 생각했으나, 당근마켓에서 일하면서 직관이 좋은 친구들을 보면서 '좋은 직관이 중요하구나'를 알 수 있었다고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연사 say &quot;데이터는 과거와 현재만 알 수 있기 때문에 미래가 다른 흐름을 하고 있다면 직관이 필요합니다. 직관은 새로운 그림을 그리는 용기같습니다.&amp;nbsp;&lt;b&gt;데이터와 직관은 서로 반대되는 것이 아닌 상호보완 관계라고 생각합니다.&lt;/b&gt;&amp;nbsp;데이터를 많이 알아야 좋은 직관을 알수 있고 좋은 직관은 데이터를 잘 해석하는데 도움이 된다고 생각합니다. 전체적인 큰 그림은 pm의 직관이 중요하고 그 큰그림을 그리는 과정에서 작은 부분에 대해서는 데이터를 바라보는게 중요하다고 생각합니다. &quot;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;프로덕트 매니저로서의 데이터 활용법&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;우선순위와 문제 정의하기
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;'동네생활 검색 고도화'의 우선순위를 의사결정하기 위한 분석
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스의 이용자 대비 검색 이용자 수&lt;/li&gt;
&lt;li&gt;당근마켓 다른 버티컬 서비스 대비 검색 후 CTR. 전환율 등&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;'동네 생활 검색의 문제'를 정의하기 위한 분석 : 검색이 유저들의 문제를 잘 해결하고 있는지!
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인기검색어&lt;/li&gt;
&lt;li&gt;검색 후 클릭 / 이탈 패턴 등등&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;검색 설계 가이드 ; 구체적인 문제 정의 :분석을 통해 경험 설계 가이드 제공&lt;/li&gt;
&lt;li&gt;실험으로 결과 확인하기 : 동네 생활 검색 CTR 144.7% 상승&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;당근마켓의 실험 문화&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참조 :&amp;nbsp;&lt;a href=&quot;https://medium.com/daangn/1%EC%A3%BC-1%EA%B0%9C-%EC%8B%A4%ED%97%98%ED%95%98%EB%8A%94-%ED%94%84%EB%A1%9C%EB%8D%95%ED%8A%B8-%ED%8C%80%EC%9D%B4-%EB%90%98%EB%8A%94-%EC%97%AC%EC%A0%95-b8a4c337a8e1&quot;&gt;1주 1개 실험하는 프로덕트 팀이 되는 여정 - 당근마켓 팀블로그&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당근마켓의 경우, 분석가의 가이드와 탬플릿을 채워가다보면 실험분석을 누구나 할 수 있게 되었다고 합니다.&amp;nbsp;각 팀이 쉽게 시작할 수 있고 승자를 배포할 수있습니다.이러한 모든 실험들은 한 공간에서 확인이 가능하고 전사적으로 공유하면서 실험을 통해 배운 것을 공유한다고 합니다.&amp;nbsp;( 레슨런만 따로 모아 볼 수 있는 공간도 존재합니다 )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 실제로 중고거래팀이 실험을 하는 방법입니다.&amp;nbsp;'사실을 알기 위해 실험을 하지만, 실험결과가 우리의 의사결정을 정해주는 것은 아니다' 라고 생각하며 의사결정을 할 때는 데이터 뿐만 아니라 다양한 요인들을 함께 고려해서 결정한다고 합니다.따라서 실험결과가 나왔더라도 바로 결과에 따라 배포하지 않고 팀이 함께 모여서 결과에 대해서 이야기를 하고 의사결정을 하게 된다고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;1부 세미나를 듣고 느낀점 / 배운점 / 벤치마킹 할 점&lt;/b&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;연사의 경우 PM 이었으나 데이터 분석가에게도 가설을 세우고 실제로 분석했을 때&amp;nbsp;**'의미없는 결과'**가 나오는 경우가 왕왕 존재합니다.&amp;nbsp; 이런경우 연사처럼 숨기지 말고 팀원과 실패도 공유해서 더 발전하고 배우는 계기로 가져가야겠다고 생각했습니다.&lt;/li&gt;
&lt;li&gt;저의 경우 PO분들처럼 직관이 부족하기 때문에 다양한 경험을 하면서 데이터로&lt;b&gt;만&lt;/b&gt;&amp;nbsp;제품을 보는 것이 아닌 PO분들의 생각도 쏙쏙 배워서 성장해야겠다고 생각했습니다&lt;/li&gt;
&lt;li&gt;당근마켓의 실험은 전사적으로 공유되고 처음한 사람도 쉽게 할 수 있도록 정형화된 가이드가 존재한다고 합니다. 저도 차근차근 야놀자에서&amp;nbsp;&amp;nbsp;통계공부와..... a/b테스트 경험을 쌓으면서 다양한 기록을 만들어 두고 싶습니다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;2. 알아두면 쓸데있는 잡다한 A/B 테스트 이야기&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;lt;세부 목차&amp;gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;A/B 테스트란?&lt;/li&gt;
&lt;li&gt;왜 하는가?&lt;/li&gt;
&lt;li&gt;어떻게 하는가?&lt;/li&gt;
&lt;li&gt;A/B 테스트시 주의할 점.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;A/B 테스트란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존버전과 수정버전을 보여주고 어떤 성과가 더 나은지를 파악하는 정량적인 평가.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여기서 성과란, 개선된 서비스의 목표하는 바에 따라 달라짐. ex, 페이지 전환율, 전환율 , 회원가입률&lt;/li&gt;
&lt;li&gt;UI 변경이 있는 ab 테스트가 있는 것도 없는 것도 있음 ex, 알고리즘 변경&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;왜 하는가?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인과관계를 찾아내기 위해서 함&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상관관계는 인과관계를 대변하지 않는다.&amp;nbsp;ex, 우산과 비는 상관관계는 있으나, 인과관계는 없다.&lt;/li&gt;
&lt;li&gt;인과관계를 찾아내기 위함.
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;쉬운문제
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;아이스크림 판매량 &amp;rarr; 물놀이 사고 빈도 : 같은 트렌드를 발견함&lt;/li&gt;
&lt;li&gt;날씨 &amp;rarr; 아이스크림 판매량 &amp;rarr; 물놀이 사고 빈도 : 진정한 판단은 날씨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;좀 더 어려운 무제
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;디자인 변경 &amp;rarr; 회원 가입 증가 한다고 말할 수 있는가? 경쟁 서비스의 변화, 다른 요인이 아닌 진정한 인과관계를 찾기 위함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;어떻게 하는가?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 목표 및 가설 설정 &amp;rarr; 실험 설계 &amp;rarr; 개발 &amp;rarr; A/B 테스트 &amp;rarr; 실험 결과 해석 &amp;rarr; 의사 결정&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;테스트 목표 및 가설 설정&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실험을 하려는 이유 : 왜 실험을 해야하는지 고민하는단계 ( ex, 트윗 쓰기 기능을 많은 사람들이 경험 했으면 좋겠다. )&lt;/li&gt;
&lt;li&gt;실험 가설 : 예상하는 원인과 결과 ( ex, 화면 왼쪽에 있는 버튼을 오른쪽으로 옮기면 클릭률이 올라갈 것이다. )&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;실험 설계&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;핵심지표 : 실험을 통해 개선하고 싶은 핵심 목표 ( ex, 트윗 작성 버튼 클릭률 )&lt;/li&gt;
&lt;li&gt;보조지표 : 핵심 지표 이외에 추가로 봐야하는 지표 ( ex, 트윗 작성률 )
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하나가 아니라 여러개가 될 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;가드레일 지표 : 실험의 영향으로 떨어지면(혹은 올라가면) 안되는 주요지표 ( ex, 이탈률, Page Load Time(PLT) )
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;오른쪽에 위치한 버튼은 실수로 클릭 할 수있는데, 그러면 사용자는 의도치 않은 동작을 방법해서 피로함 &amp;rarr; 앱 종료함.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;실험을 위한 사전 작업 : 개발이 필요한지, 문구, 혹은 디자인만 필요한지 - 작업리스트 작성&lt;/li&gt;
&lt;li&gt;실험 대상 : 실험의 대상 정의 ( ex, 안드로이드 1.0.1 버전 / 특정 국가 등 )
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;보통은 사용자가 작은 그룹을 테스트로 함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;실험 기간과 규모&lt;/b&gt;&amp;nbsp;: 테스트는 기회비용을 가지고 있다. 테스트가 길어지면, 기회 비용이 비싸다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&quot;표본이 많으면 많을 수록 좋은가?&quot; ( p-value의 함정 .. )&lt;/li&gt;
&lt;li&gt;MDE 를 통한 최소 효과 크기를 구해야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;개발&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;A/B 테스트&lt;/b&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테스트가 제대로 되고 있는가
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실험군과 대조군이 랜덤하게 나누어지고 있나&lt;/li&gt;
&lt;li&gt;실험을 하는 동안 사용자 경험은 어떤가&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;테스트를 하는 인간의 욕망
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;내가 원하는 결과를 봤을때 실험을 멈추고 싶다 ( peeking problem )&lt;/li&gt;
&lt;li&gt;내가 원하는 결과를 보기까지 실험을 계속하고 싶다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;실험 결과 해석&lt;/b&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실험 결과 : A,B 실험군의 수, 지표 평균, p-value 등 주요 실험 결과 정리&lt;/li&gt;
&lt;li&gt;실험 결과 분석 : 사용자 군 별로 쪼개보거나 보조지표를 분석하는 등 상세 분석&lt;/li&gt;
&lt;li&gt;실험을 통해 배운점 : 서비스의 사용자는 끊임없이 변한다. 서비스를 학습을 하면서 다르고, 경쟁 서비스도 발전하기 때문에 서비스의 사용자가 계속 변한다고 생각하면 좋다.
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;A/B 의 결과가 언제까지 유용할 것인가?&lt;/li&gt;
&lt;li&gt;이 실험을 통해 배운게 어디까지 보편적인가?&lt;/li&gt;
&lt;/ol&gt;
&lt;b&gt;'이 실험을 통해 배운 레슨런이 영원하지 않다' 는 것을 기억하기.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;그래서 두가지 질문을 하는게 좋다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;의사결정&lt;/b&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실험 결과 != 의사결정&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;실험 기간과 규모에 대하여...&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테스트는 기회비용을 가지고 있다. 테스트가 길어지면, 기회 비용이 비싸다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&quot;표본이 많으면 많을 수록 좋은가?&quot; -&amp;nbsp;&lt;b&gt;No&lt;/b&gt;&amp;nbsp;( 그에 대한 자세한 답변은 &amp;gt;&amp;gt;&amp;nbsp;&lt;a href=&quot;https://www.datarian.io/blog/dont-be-overwhelmed-by-pvalue&quot;&gt;p-value의 함정&lt;/a&gt;&amp;nbsp;확인 )&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;실험 기간과 규모를 구하는 방법
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;샘플사이즈 계산기를 이용한다.&lt;/li&gt;
&lt;li&gt;샘플사이즈를 계산하기 위해서는&amp;nbsp;&lt;b&gt;MDE를 정해야한다...&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;적절한 표본크기를 정하기 어려운 현실적인 문제들..
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최소 효과 크기(MDE)를 정하기 쉽지 않음&lt;/li&gt;
&lt;li&gt;서비스의 트래픽이 충분하지 않음&lt;/li&gt;
&lt;li&gt;서비스의 트래픽은 충분하지만, 동시에 여러 실험을 한다면 한가지 실험에 할당할 수 있는 규모에 한계가 있음&lt;/li&gt;
&lt;li&gt;특정 머신러닝 모델의 경우 학습을 위한 최소 트래픽이 필요한 경우도 있음&lt;/li&gt;
&lt;li&gt;&lt;b&gt;고객의 행동이 주기에 영향을 받음&lt;/b&gt;&amp;nbsp;( ex, 주중과 주말의 행동이 다름. 따라서 최소한 일주일이 필요함 )&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;보통은 데이터 분석가의 경험을 통해서 표본크기를 정한다. 꼼꼼한 부분보다 경험적으로 결정하는게 많다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;A/B 테스트시 주의할 점&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실험 초반에 지표가 갑자기 많이 올라가는데 어떻게 해야 하나요?
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;신기 효과 ( Novelty Effect )
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 사용자들은 단지 이 기능이 '새롭기' 때문에 사용해볼 수 있음&lt;/li&gt;
&lt;li&gt;긍적적인 지표가 단기간 동안에만 지속됨&lt;/li&gt;
&lt;li&gt;신기효과를 피하는 방법
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;A/B 각 그룹에서 신규 사용자만 뽑아서 지표를 확인&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;실험 시작 이후 N회차 방문 별로 세그먼트를 쪼개어 데이터를 확인 ( 더이상 신규 기능이 새롭지 않게 됐을때에도 기능을 사용할 것인가를 보기 위함)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;실험을 길게 진행&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;초두 효과 ( Primacy Effect )
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자들이 새 기능에 적응하는데 시간이 걸릴 수 있음&lt;/li&gt;
&lt;li&gt;시간이 지날수록 새 기능에 학습을 하기 때문에 반응을 하기 시작함&lt;/li&gt;
&lt;li&gt;초두 효과를 피하는 법
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;신기효과 피하는 법과 동일&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;테스트를 하는 인간의 욕망
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;내가 원하는 결과를 봤을때 실험을 멈추고 싶다 ( peeking problem )&lt;/li&gt;
&lt;li&gt;내가 원하는 결과를 보기까지 실험을 계속하고 싶다&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;A와 B가 비슷하면 어떻게 해야 하나요?
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;근소한 차이가 중요한가?
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;No
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비슷하다고 결론을 낸다&lt;/li&gt;
&lt;li&gt;다른실험을 시작한다&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Yes
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;통계적으로 유의성을 확보할때 까지 실험을 계속한다. ( x )&lt;/li&gt;
&lt;li&gt;보조 지표를 확인한다 ( o )&lt;/li&gt;
&lt;li&gt;고객 세그먼트를 나누어 지표를 분석한다 ( o )&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;2부 세미나를 듣고 느낀점 / 배운점 / 벤치마킹 할 점&lt;/b&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;공부해도 휘발이 강한 애증의&amp;nbsp;통계에 대해 조금 더 깊게 공부 해야겠다 느꼈습니다.&lt;/li&gt;
&lt;li&gt;신기효과/초두효과를 피하는 방법을 늘 &amp;lt;오래 실험하기&amp;gt;로만 생각했는데, 그룹을 나누어 분석한다는 방법을 깨닫게 되었습니다.&lt;/li&gt;
&lt;li&gt;실험 결과와 의사결정이 같지 않다는 점을 더 명심하게 되었습니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>DATA  ANALYSIS/Analysis</category>
      <category>A/B테스트</category>
      <category>데이터리안</category>
      <author>Rmsid01</author>
      <guid isPermaLink="true">https://hazel01.tistory.com/123</guid>
      <comments>https://hazel01.tistory.com/123#entry123comment</comments>
      <pubDate>Wed, 23 Nov 2022 22:33:02 +0900</pubDate>
    </item>
    <item>
      <title>Pandas - 데이터 분석할 때 유용한 Groupby</title>
      <link>https://hazel01.tistory.com/120</link>
      <description>&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;데이터를 다루기 위해, 여러 변수를 만지다 보면, groupby가 굉장히 유용하다는 것을 느낀다. &lt;br&gt;그래서, 기초부터 응용 버전까지 한 번에 정리하려고 한다.&lt;br&gt; &lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;0. Groupby 란,&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;SQL groupby 명령어와 같은 느낌인데, 데이터를 split -&amp;gt; apply -&amp;gt; combine 하는 과정을 거쳐서 연산한다.&lt;br&gt;아래에서 다양한, 그룹바이 예시를 하기 위해서 데이터 프레임을 만들어 준다. &lt;br&gt; &lt;br&gt; &lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. groupby를 하는 방법 : 기본적인 groupby&lt;/b&gt;&lt;/h3&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;01. 한개 열을 기준으로 groupby : 집계&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그룹바이는, 그룹 바이만 하면 안 되고, 집계 함수를 같이 써주어야 내가 원하는 데이터 프레임 형태가 된다.&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #333333;&quot;&gt;묶어 주고 싶은 컬럼을 by = [' col ' ] 넣어주면 된다. by는 생략해도 된다. &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #333333;&quot;&gt;아래 코드는 최소 수량을 알기 위해, min을 사용하였지만, 다른 집계 함수들도 사용할 수 있다.&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #333333;&quot;&gt;[ count, min, mean, sum, max, cumsum ] &lt;/span&gt;&lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;# min: 상품번호별 판매된 최소 수량
df.groupby(by=['product_id']).min()&lt;/code&gt;&lt;/pre&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1354&quot; data-origin-height=&quot;267&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Tnm1A/btqVZSM67aC/MKdJscEERiV4TEkL9slEck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Tnm1A/btqVZSM67aC/MKdJscEERiV4TEkL9slEck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Tnm1A/btqVZSM67aC/MKdJscEERiV4TEkL9slEck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTnm1A%2FbtqVZSM67aC%2FMKdJscEERiV4TEkL9slEck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1354&quot; height=&quot;267&quot; data-origin-width=&quot;1354&quot; data-origin-height=&quot;267&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;그룹바이를 통해, P1을 가지고 있는 ROW중에서 가장 최소인 것들만 뽑아진 것을 확인할 수 있다. &lt;br&gt; &lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;02. 두개 이상의 열을 기준으로 groupby 하기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;두 개 이상의 열을 기준으로도, 그룹바이를 할 수 있다. &lt;br&gt;그러면, index 가 multi index 가 된다.&lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;df_grouped = df.groupby(['product_id','user_id']).sum()&lt;/code&gt;&lt;/pre&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;234&quot; data-origin-height=&quot;251&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IEqox/btqVV2WIFLb/BewuyERKpm0UG3a8DTGAh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IEqox/btqVV2WIFLb/BewuyERKpm0UG3a8DTGAh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IEqox/btqVV2WIFLb/BewuyERKpm0UG3a8DTGAh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIEqox%2FbtqVV2WIFLb%2FBewuyERKpm0UG3a8DTGAh0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;234&quot; height=&quot;251&quot; data-origin-width=&quot;234&quot; data-origin-height=&quot;251&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt; &lt;br&gt;** 이렇게 인덱스 형태가 되면, 데이터를 다룰 때 귀찮아질 때가 있다. 그럴 때, groupby안에서 as_index를 False로 넣어주면, 기준 칼럼이 인덱스로 가지 않는다. &lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;df_grouped = df.groupby(['product_id','user_id'], as_index = False).sum()&lt;/code&gt;&lt;/pre&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;278&quot; data-origin-height=&quot;231&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EjJlJ/btqV2V24eaM/PfiIJL9MRLWnlwPbISDWV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EjJlJ/btqV2V24eaM/PfiIJL9MRLWnlwPbISDWV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EjJlJ/btqV2V24eaM/PfiIJL9MRLWnlwPbISDWV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEjJlJ%2FbtqV2V24eaM%2FPfiIJL9MRLWnlwPbISDWV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;278&quot; height=&quot;231&quot; data-origin-width=&quot;278&quot; data-origin-height=&quot;231&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;** 아래의 코드처럼 특정 컬럼 이름을 명시해주면, 그 컬럼만 적용받을 수 있다.&lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;df.groupby(['product_id','user_id'])['point'].sum()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt; &lt;br&gt;2. grouby를 한 후, index 를 다루기&lt;br&gt; &lt;br&gt;3. groupby된 데이터를 가지고 원하는 정보 추출 &lt;/p&gt;</description>
      <category>DATA  ANALYSIS/Python with Data</category>
      <author>Rmsid01</author>
      <guid isPermaLink="true">https://hazel01.tistory.com/120</guid>
      <comments>https://hazel01.tistory.com/120#entry120comment</comments>
      <pubDate>Thu, 6 Oct 2022 23:24:36 +0900</pubDate>
    </item>
    <item>
      <title>[ Python : Sequence ] List, Comprehension( 다중 if 문 , filter, map 사용 ),</title>
      <link>https://hazel01.tistory.com/119</link>
      <description>&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Chapter 03 : Sequence&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;: 요소가 연속적으로 나열되어있는 자료형 &lt;br&gt;- 자료가 담겨있는 갯수&lt;br&gt;1 ) 컨테이너 형 ( container ) : 서로 다른 자료형을 담는다.&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ex, list, tuple , collections.deque&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2 ) 플랫형 ( flat ) : 단일 자료형만 담는다. 한개의 자료형&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ex, &lt;/span&gt;&lt;span style=&quot;color: #808080;&quot;&gt;str, bytes , bytearray , array.array , memoryview &lt;/span&gt;&lt;br&gt; &lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 가변형 / 불변형&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1 ) &lt;/span&gt;&lt;span style=&quot;color: #808080;&quot;&gt;가변형 : list, bytearray , array.array , memoryview , deque&lt;br&gt;&lt;/span&gt;&lt;span style=&quot;color: #808080;&quot;&gt;2 ) 불변형 : tuple, str , bytes&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. List &lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;b&gt;: 수정가능한, 자료형&lt;/b&gt;&lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;chars = 'abcdefg'
list1 = []
for s in chars :
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;list1.append(ord(s))
print(list1)

# output : [97, 98, 99, 100, 101, 102, 103]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt; &lt;br&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1 ) Comprehending List &lt;/span&gt;&lt;/b&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: 위에서 반복문으로 만든 list를 아래의 Comprehension 으로 간단하게 만들 수 있다. 속도 측면에서도 더 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;list2 = [ord(s) for s in chars]
print( list2 )

# output: [97, 98, 99, 100, 101, 102, 103]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt; &lt;br&gt;- &lt;span style=&quot;color: #000000;&quot;&gt;Comprehension 을 사용하는 다른 방법.&lt;/span&gt;&lt;br&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;a. 단일 if 문을 사용하기. &lt;/span&gt;&lt;/b&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: if 문을 사용하여, 내가 원하는 조건의 값만 받아올 수 있다. &lt;/span&gt;&lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;list3 = [ord(s) for s in chars if ord(s) &amp;gt; 100]

# output : [101, 102, 103]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt; &lt;br&gt;&lt;b&gt;b. 다중 If문 사용하기&lt;/b&gt;&lt;br&gt;: 다중 if 문을 사용하여, 조건을 받아올 수 있다.&lt;br&gt; &lt;br&gt;&lt;b&gt;c. map 사용하기&lt;/b&gt;&lt;br&gt;: map 은 여러개의 데이터를 지정된 함수로 처리해주는 함수이다. &lt;br&gt;보통은 map( 변환 함수, 리스트 ) 혹은 map( 변환 함수, 튜플 ) 로 사용한다.&lt;br&gt;map(lambda x : x if x==0 else 1) 처럼, lambda를 이용하여 조건을 걸 수 도 있습니다.&lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;list4 = list(map(ord, chars))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt; &lt;br&gt;&lt;b&gt;d. filter 사용하기&lt;/b&gt;&lt;br&gt;: filter ( 함수, 값 ) 을 넣어서, 값에 대해서 원하는 조건의 값만 나오도록 해준다. &lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;list5 = list(filter(lambda x: x &amp;gt; 100, map(ord, chars)))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt; &lt;/p&gt;</description>
      <category>PROGRAMMING/Python</category>
      <author>Rmsid01</author>
      <guid isPermaLink="true">https://hazel01.tistory.com/119</guid>
      <comments>https://hazel01.tistory.com/119#entry119comment</comments>
      <pubDate>Wed, 5 Oct 2022 23:24:22 +0900</pubDate>
    </item>
    <item>
      <title>[ SQL : with recursive,  SET ] 프로그래머스 : 입양 시각 구하기(2)</title>
      <link>https://hazel01.tistory.com/118</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;- 문제 설명&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ANIMAL_OUTS&lt;span&gt;&amp;nbsp;&lt;/span&gt;테이블은 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블입니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;ANIMAL_OUTS&lt;span&gt;&amp;nbsp;&lt;/span&gt;테이블 구조는 다음과 같으며,&lt;span&gt;&amp;nbsp;&lt;/span&gt;ANIMAL_ID,&lt;span&gt;&amp;nbsp;&lt;/span&gt;ANIMAL_TYPE,&lt;span&gt;&amp;nbsp;&lt;/span&gt;DATETIME,&lt;span&gt;&amp;nbsp;&lt;/span&gt;NAME,&lt;span&gt;&amp;nbsp;&lt;/span&gt;SEX_UPON_OUTCOME는 각각 동물의 아이디, 생물 종, 입양일, 이름, 성별 및 중성화 여부를 나타냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NAMETYPENULLABLE&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ANIMAL_ID&lt;/td&gt;
&lt;td&gt;VARCHAR(N)&lt;/td&gt;
&lt;td&gt;FALSE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ANIMAL_TYPE&lt;/td&gt;
&lt;td&gt;VARCHAR(N)&lt;/td&gt;
&lt;td&gt;FALSE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DATETIME&lt;/td&gt;
&lt;td&gt;DATETIME&lt;/td&gt;
&lt;td&gt;FALSE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NAME&lt;/td&gt;
&lt;td&gt;VARCHAR(N)&lt;/td&gt;
&lt;td&gt;TRUE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SEX_UPON_OUTCOME&lt;/td&gt;
&lt;td&gt;VARCHAR(N)&lt;/td&gt;
&lt;td&gt;FALSE&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 합니다. 0시부터 23시까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성해주세요. 이때 결과는 시간대 순으로 정렬해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제 원본&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/59413&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://programmers.co.kr/learn/courses/30/lessons/59413&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1652400620906&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 입양 시각 구하기(2)&quot; data-og-description=&quot;ANIMAL_OUTS 테이블은 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블입니다. ANIMAL_OUTS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, NAME, SEX_UPON_OUTCOME는 각각 동물의 아이디, 생물&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/59413&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/59413&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bGFT4R/hyOnUJ4lSn/M54lt2QNndzpg7BufUezX0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/d6E1ND/hyOnV3hlBJ/CVFQiNFedYkX1ZQNjfLl80/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/59413&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/59413&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bGFT4R/hyOnUJ4lSn/M54lt2QNndzpg7BufUezX0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/d6E1ND/hyOnV3hlBJ/CVFQiNFedYkX1ZQNjfLl80/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;코딩테스트 연습 - 입양 시각 구하기(2)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;ANIMAL_OUTS 테이블은 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블입니다. ANIMAL_OUTS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, NAME, SEX_UPON_OUTCOME는 각각 동물의 아이디, 생물&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt;&amp;gt; 정답&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- with recursive 를 이용해서 푸는 코드&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;with recursive temp as (
    (select 0 HOUR)
    union
    (select HOUR+1 from temp where HOUR &amp;lt; 23)
)

select HOUR, ifnull(c.COUNT, 0)
from temp natural left outer join (
    select HOUR(DATETIME) HOUR, count(*) COUNT
    from ANIMAL_OUTS
    group by HOUR
    order by HOUR) c&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- set을 사용&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt; SET @ROWNUM :=-1;
SELECT A1 HOUR, IFNULL(COUNT,0) COUNT
FROM
    (SELECT @ROWNUM :=@ROWNUM+1 A1, ANIMAL_OUTS.NAME A2 
        FROM ANIMAL_OUTS 
        WHERE @ROWNUM&amp;lt;23
        ) A 
LEFT JOIN 
		(SELECT HOUR(DATETIME) HOUR, COUNT(HOUR(DATETIME)) COUNT 
        	FROM ANIMAL_OUTS
            GROUP BY HOUR
            ORDER BY HOUR ASC) B 
        ON A.A1=B.HOUR&lt;/code&gt;&lt;/pre&gt;</description>
      <category>DATA  ANALYSIS/SQL</category>
      <category>sql</category>
      <category>입양 시각 구하기(2)</category>
      <category>코딩테스트</category>
      <author>Rmsid01</author>
      <guid isPermaLink="true">https://hazel01.tistory.com/118</guid>
      <comments>https://hazel01.tistory.com/118#entry118comment</comments>
      <pubDate>Fri, 13 May 2022 19:55:14 +0900</pubDate>
    </item>
    <item>
      <title>[ Pandas ] 데이터프레임 데이터의 '{}' 안에 있는 값 추출하기</title>
      <link>https://hazel01.tistory.com/117</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;상황&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 데이터와 같이, 데이터프레임의 각 값에는 딕셔너리로 들어가 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딕셔너리 데이터 중, user_seq를 뽑아서 하나의 컬럼으로 만들고 싶다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;232&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dN4tEZ/btrBFbRwLyh/00OSH29aUsh1EU16cKp9w0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dN4tEZ/btrBFbRwLyh/00OSH29aUsh1EU16cKp9w0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dN4tEZ/btrBFbRwLyh/00OSH29aUsh1EU16cKp9w0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdN4tEZ%2FbtrBFbRwLyh%2F00OSH29aUsh1EU16cKp9w0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;459&quot; height=&quot;232&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;232&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;해결 과정&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 데이터의 형태를 좀더 깊게 보니, 딕셔너리를 형태를 &quot; &quot; 로 감싸져있어서, 타입이 string 이었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1101&quot; data-origin-height=&quot;71&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1c8Mg/btrBsE2jeJ2/0Kxk9f9lUtksRo0AWKOFF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1c8Mg/btrBsE2jeJ2/0Kxk9f9lUtksRo0AWKOFF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1c8Mg/btrBsE2jeJ2/0Kxk9f9lUtksRo0AWKOFF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1c8Mg%2FbtrBsE2jeJ2%2F0Kxk9f9lUtksRo0AWKOFF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;938&quot; height=&quot;60&quot; data-origin-width=&quot;1101&quot; data-origin-height=&quot;71&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 따라서, 이부분을 먼저 dict형태로 변경시켜줘어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 변경하는 방법은 json 라이브러리를 불러와서, json.loads() 를 해주는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 아래와 같이,&amp;nbsp; ' ' 는 사라지고, 타입이 dict 로 변하게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1012&quot; data-origin-height=&quot;155&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B5klJ/btrBF5qefbJ/D8L9p0TLsfXX0f8Jgttso1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B5klJ/btrBF5qefbJ/D8L9p0TLsfXX0f8Jgttso1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B5klJ/btrBF5qefbJ/D8L9p0TLsfXX0f8Jgttso1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB5klJ%2FbtrBF5qefbJ%2FD8L9p0TLsfXX0f8Jgttso1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1012&quot; height=&quot;155&quot; data-origin-width=&quot;1012&quot; data-origin-height=&quot;155&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 이때, dict 여서, 단순히&amp;nbsp; 아래와 같이 코드를 짜면, 에러가 발생하게 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1652071375754&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;data['af_user_seq']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1012&quot; data-origin-height=&quot;513&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3nGOp/btrBzdX5Ha7/GHvBbqRPwIp7prSq0RrKTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3nGOp/btrBzdX5Ha7/GHvBbqRPwIp7prSq0RrKTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3nGOp/btrBzdX5Ha7/GHvBbqRPwIp7prSq0RrKTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3nGOp%2FbtrBzdX5Ha7%2FGHvBbqRPwIp7prSq0RrKTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1012&quot; height=&quot;513&quot; data-origin-width=&quot;1012&quot; data-origin-height=&quot;513&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이, 분명이 딕셔너리 keys 에는 존재하는데, 없다고 뜬다..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분을 해결하기 위해서 &lt;a href=&quot;https://sanghaklee.tistory.com/62&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://sanghaklee.tistory.com/62&lt;/a&gt;&amp;nbsp;여기 문서를 참고 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;결론, &quot;get&quot; 함수를 써주어라!&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;257&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Quk6j/btrBAZ56fYv/2QLRWrDLKpQMOPAImCRs91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Quk6j/btrBAZ56fYv/2QLRWrDLKpQMOPAImCRs91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Quk6j/btrBAZ56fYv/2QLRWrDLKpQMOPAImCRs91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQuk6j%2FbtrBAZ56fYv%2F2QLRWrDLKpQMOPAImCRs91%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;716&quot; height=&quot;257&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;257&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이, get 함수를 써주고,&amp;nbsp; 추출해주고 싶은 key 이름을 넣어주면된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DATA  ANALYSIS/Python with Data</category>
      <author>Rmsid01</author>
      <guid isPermaLink="true">https://hazel01.tistory.com/117</guid>
      <comments>https://hazel01.tistory.com/117#entry117comment</comments>
      <pubDate>Mon, 9 May 2022 13:45:57 +0900</pubDate>
    </item>
    <item>
      <title>[ Airflow ] Scheduling 개념 / execution_date</title>
      <link>https://hazel01.tistory.com/116</link>
      <description>&lt;h2 id=&quot;1.-스케쥴링-개념&quot; data-renderer-start-pos=&quot;1&quot; data-ke-size=&quot;size26&quot;&gt;1. 스케쥴링 개념&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-renderer-start-pos=&quot;13&quot; data-ke-size=&quot;size16&quot;&gt;Airflow 에서 start_date / execute_date 는 매우 헷갈리는 개념이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;start_date : DAG 스케쥴이 시작되는 시간(날짜)&lt;/li&gt;
&lt;li&gt;execution_date : 스케쥴을 한시간에 한번이라면, DAG 실행 한시간 전에 대한 시간
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 문서에서 보면, execution_date를 date로 받아들이지 말고, dag 의 고유 실행 id 로 받아들이라고 한다.&lt;/li&gt;
&lt;li&gt;그런 의미에서, 추후에 backfill 을 하더라도, 즉 나중에 해당 dag를 다시 실행하더라도 execution_date는 그대로 유지 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-renderer-start-pos=&quot;327&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;2.-스케쥴링-테스트&quot; data-renderer-start-pos=&quot;329&quot; data-ke-size=&quot;size26&quot;&gt;2. 스케쥴링 테스트&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 id=&quot;1.-catchup-=-False-,-schedule_interval-=-'*/15-*-*-*-*'&quot; data-renderer-start-pos=&quot;342&quot; data-ke-size=&quot;size23&quot;&gt;1. catchup = False , schedule_interval = '*/15 * * * *'&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;code&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;pre id=&quot;code_1651230904810&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dag = DAG(
    dag_id='date_test_dag_v1',
    start_date=datetime(2022, 4, 1, tzinfo=korea_tz),
    catchup=False,
    schedule_interval='*/15 * * * *'
)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DAG 업로드 시간 : 2022.04.21 10:05&lt;/li&gt;
&lt;li&gt;DAG 반복 주기 : 15분에 한번씩&lt;/li&gt;
&lt;li&gt;CATCH UP : False
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;False 이기 때문에, 업로드 당시, 재시작 당시 한번만 DAG 실행 되며, 그 이전에 대한 DAG는 실행 되지 않음&lt;/li&gt;
&lt;li&gt;멈췄다가 재 실행하더라도, 이전 DAG를 실행 x&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1180&quot; data-origin-height=&quot;299&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oyrSC/btrAQ7iRZ6I/wVWz6iRo1go2aohfa6ksIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oyrSC/btrAQ7iRZ6I/wVWz6iRo1go2aohfa6ksIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oyrSC/btrAQ7iRZ6I/wVWz6iRo1go2aohfa6ksIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoyrSC%2FbtrAQ7iRZ6I%2FwVWz6iRo1go2aohfa6ksIk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1180&quot; height=&quot;299&quot; data-origin-width=&quot;1180&quot; data-origin-height=&quot;299&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div data-layout=&quot;full-width&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-renderer-start-pos=&quot;1287&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;1289&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;2.-catchup-=-True-,-schedule_interval-=-'*/60-*-*-*-*'&quot; data-renderer-start-pos=&quot;1291&quot; data-ke-size=&quot;size23&quot;&gt;2. catchup = True , schedule_interval = '*/60 * * * *'&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;code&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;pre id=&quot;code_1651230936629&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dag = DAG(
    dag_id='date_test_dag_v2',
    start_date=datetime(2022, 4, 20, tzinfo=local_tz),
    catchup=True,
    schedule_interval='*/60 * * * *',
        default_args={
        'retries': 1,
        'retry_delay': timedelta(minutes=3)
    }
)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DAG 업로드 시간 : 2022.04.21 15:59&lt;/li&gt;
&lt;li&gt;DAG 반복 주기 : 1시간에 한번씩&lt;/li&gt;
&lt;li&gt;CATCH UP : True
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;True 이기 때문에, 업로드 당시, 4월 20일 3시 DAG부터 한번에 25개가 실행 됨. ( 순서대로 실행되기 때문에, 시간차 존재하긴 함. 그러나 한번에 켜짐 )
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;3&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사실 DAG 는 25개나, 한번에 켜지기때문에 느려져 재 실행되고, 그래서 Runs가 40개가 찍히는것으로 보인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;멈췄다가 다시 실행할 때, 역시 멈춘동안 돌지 못한 DAG 도 함께 실행된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div data-layout=&quot;center&quot; data-node-type=&quot;mediaSingle&quot;&gt;
&lt;div&gt;
&lt;div data-context-id=&quot;2949808350&quot; data-type=&quot;file&quot; data-node-type=&quot;media&quot; data-width=&quot;363&quot; data-height=&quot;130&quot; data-id=&quot;65ecb3f9-a060-4ee8-8073-8254dd0d09e1&quot; data-collection=&quot;contentId-2949808350&quot; data-file-name=&quot;image-20220421-072512.png&quot; data-file-size=&quot;7712&quot; data-file-mime-type=&quot;image/png&quot; data-alt=&quot;&quot;&gt;
&lt;div data-testid=&quot;media-card-view&quot;&gt;
&lt;div data-testid=&quot;media-file-card-view&quot; data-test-status=&quot;loading&quot;&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;363&quot; data-origin-height=&quot;130&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xF90x/btrAR9GZ8FN/9BcCBJKC9EY0nmZylZa4R0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xF90x/btrAR9GZ8FN/9BcCBJKC9EY0nmZylZa4R0/img.png&quot; data-alt=&quot;DAG 올리는 순간, 25개가 한번에 실행된 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xF90x/btrAR9GZ8FN/9BcCBJKC9EY0nmZylZa4R0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxF90x%2FbtrAR9GZ8FN%2F9BcCBJKC9EY0nmZylZa4R0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;363&quot; height=&quot;130&quot; data-origin-width=&quot;363&quot; data-origin-height=&quot;130&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;DAG 올리는 순간, 25개가 한번에 실행된 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-media-caption=&quot;true&quot; data-testid=&quot;media-caption&quot; data-renderer-start-pos=&quot;1907&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특이점 : 4월 20일이라고 설정하더라도 00시부터 시작하는 것이 아니라, 4시에 돌아가는 3시부터 시작되는 것으로 보인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div data-layout=&quot;full-width&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1206&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dNnCwP/btrAPq4240C/mo1f72YA3WiH63KbCkbxp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dNnCwP/btrAPq4240C/mo1f72YA3WiH63KbCkbxp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dNnCwP/btrAPq4240C/mo1f72YA3WiH63KbCkbxp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdNnCwP%2FbtrAPq4240C%2Fmo1f72YA3WiH63KbCkbxp1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1206&quot; height=&quot;300&quot; data-origin-width=&quot;1206&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-renderer-start-pos=&quot;2653&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 id=&quot;3.-Catch-up-을-설정했을-때(True)와-아닐-때(False),-가져올-데이터를-어떻게-구별하는가?&quot; data-renderer-start-pos=&quot;2653&quot; data-ke-size=&quot;size26&quot;&gt;3. Catch up 을 설정했을 때(True)와 아닐 때(False), 가져올 데이터를 어떻게 구별하는가?&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-renderer-start-pos=&quot;2715&quot; data-ke-size=&quot;size16&quot;&gt;Q. Backfill 을 실행하여 &lt;b&gt;&amp;lsquo;과거 데이터&amp;rsquo;&lt;/b&gt;만을 가져오거나 ?! 혹은 Catch up을 하여 이전 DAG를 실행하여 &amp;lsquo;이전 데이터&amp;rsquo;를 가져온다!? 그렇다면, &amp;lsquo;이전 데이터&amp;rsquo;라는 것은 어떻게 아는가?!&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;2831&quot; data-ke-size=&quot;size16&quot;&gt;A. execution_date 를 사용하여, &lt;b&gt;&lt;span style=&quot;color: #000000;&quot; data-renderer-mark=&quot;true&quot; data-text-custom-color=&quot;#bf2600&quot;&gt;코드&lt;/span&gt;&lt;/b&gt;에 날짜 조건을 걸어주어 사용한다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;2880&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;2882&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;2884&quot; data-ke-size=&quot;size16&quot;&gt;실제, 코드가 전체 데이터를 가져와서 사용하는 경우 ( 혹은 날짜와 관련 없는 데이터의 경우 ) 에는 catch up 설정 혹은 backfill 에 대해서 신경쓰지 않아도 되는 것으로 보인다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;2994&quot; data-ke-size=&quot;size16&quot;&gt;즉, 여러번 실행 했을 때나, 한번만 실행 했을 때나 DAG 실행 당시까지 쌓인 전체 데이터를 가져와서 처리한다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;3060&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;3062&quot; data-ke-size=&quot;size16&quot;&gt;그러나, execution_date 가 의미가 있으려면, execution_date로 코드 상에서 조건을 걸어주어 해당 날짜 이후 데이터 혹은 이전의 데이터를 가져오는 식으로 사용한다.&lt;/p&gt;
&lt;div data-layout=&quot;center&quot; data-width=&quot;50&quot; data-node-type=&quot;mediaSingle&quot;&gt;
&lt;div&gt;
&lt;div data-context-id=&quot;2949808350&quot; data-type=&quot;file&quot; data-node-type=&quot;media&quot; data-width=&quot;1017&quot; data-height=&quot;282&quot; data-id=&quot;f69f63da-09bd-4343-aada-cad19cf01752&quot; data-collection=&quot;contentId-2949808350&quot; data-file-name=&quot;image-20220421-074048.png&quot; data-file-size=&quot;70560&quot; data-file-mime-type=&quot;image/png&quot; data-alt=&quot;&quot;&gt;
&lt;div data-testid=&quot;media-card-view&quot;&gt;
&lt;div data-testid=&quot;media-file-card-view&quot; data-test-status=&quot;loading&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-renderer-start-pos=&quot;3201&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1017&quot; data-origin-height=&quot;282&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/S8Ri8/btrAR91iWe2/M2HBwSHImFg43C4HYX8521/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/S8Ri8/btrAR91iWe2/M2HBwSHImFg43C4HYX8521/img.png&quot; data-alt=&quot;참조 : 오늘의 집 기술 블로그 [ 링크 : 버킷플레이스 Airflow 도입기 - 오늘의집 블로그 ]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/S8Ri8/btrAR91iWe2/M2HBwSHImFg43C4HYX8521/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FS8Ri8%2FbtrAR91iWe2%2FM2HBwSHImFg43C4HYX8521%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1017&quot; height=&quot;282&quot; data-origin-width=&quot;1017&quot; data-origin-height=&quot;282&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;참조 : 오늘의 집 기술 블로그 [ 링크 : 버킷플레이스 Airflow 도입기 - 오늘의집 블로그 ]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;3201&quot; data-ke-size=&quot;size16&quot;&gt;- 변수로 받는 DATE 는 execute date 만 가능하다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;3239&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;4.-DAG-가-에러가-나온다면?-execute_date는-어떻게-되는가?&quot; data-renderer-start-pos=&quot;3241&quot; data-ke-size=&quot;size26&quot;&gt;4. DAG 가 에러가 나온다면? execution_date는 어떻게 되는가?&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-renderer-start-pos=&quot;3284&quot; data-ke-size=&quot;size16&quot;&gt;그냥 무시하고 증가된다.&lt;span data-renderer-mark=&quot;true&quot;&gt; 따라서 execution_date 를 이용하려면 처리가 필요해 보인다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;3337&quot; data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 그래서 backfill 이라는 개념이 편하게 동작되는 것으로 보인다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;3379&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DATA ENGINEERING/Data Engineering</category>
      <category>airflow</category>
      <category>execution_date</category>
      <category>mwaa</category>
      <category>scheduling</category>
      <category>스케쥴</category>
      <author>Rmsid01</author>
      <guid isPermaLink="true">https://hazel01.tistory.com/116</guid>
      <comments>https://hazel01.tistory.com/116#entry116comment</comments>
      <pubDate>Fri, 29 Apr 2022 20:17:27 +0900</pubDate>
    </item>
    <item>
      <title>[awswrangler] 데이터프레임을 Redshift로 한번에 넣는 방법</title>
      <link>https://hazel01.tistory.com/115</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;aws 서비스에서, 데이터를 insert 가 아닌, dataframe으로 한번에 넣는 방법으로 'awswrangler' 모듈이 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약, awswrangler 를 사용하지 않는다면, 아래와 같이, insert into 구문을 사용해야 하며, 많은 데이터를 넣기 위해서는 for 문을 해야하는 매우 비 효율적인 방식을 사용해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1649827032755&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cur = get_Redshift_connection()

sql = &quot;BEGIN; DELETE FROM {schema}.{table};&quot;.format(schema=schema, table=table)
sql += f&quot;&quot;&quot;INSERT INTO {schema}.{table} VALUES ( '2022-01-01', 1);&quot;&quot;&quot;
sql += &quot;END;&quot;

cur.execute(sql)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 부분을 해결하기 위해서, 데이터 프레임 형태의 데이터를 그대로 올리기를 원했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 방법이 존재하는 것 같았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. pandas_redshift 를 이용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: pandas_to_redshift 를 이용하여, 데이터를 프레임 형태로 그대로 넣어줄 수 있다.&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import pandas_redshift as pr

pr.pandas_to_redshift(data_frame=test_df,
                      redshift_table_name=to_table)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;** 이 방법을 사용하지 않는 이유는.. MWAA 로 진행중인데, import 오류로 안맞아서 일단은 보류 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. s3에 데이터를 올린후, s3 -&amp;gt; Redshift 로 옮기기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: airflow 를 이용하고 있는 중이라, 이 방법도 존재하였다. 그러나, 많은 양의 데이터도 아닌데 굳이 s3에 담아야 할까? 라는 고민을 하였고, 이 방법은 패스하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로, airflow 에는&lt;span style=&quot;background-color: #f6e199; color: #24292f;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span data-hydro-click=&quot;{&amp;quot;event_type&amp;quot;:&amp;quot;code_navigation.click_on_symbol&amp;quot;,&amp;quot;payload&amp;quot;:{&amp;quot;action&amp;quot;:&amp;quot;click_on_symbol&amp;quot;,&amp;quot;repository_id&amp;quot;:469983992,&amp;quot;ref&amp;quot;:&amp;quot;bafd78d0dd3963bd0946364f8450ed7d944afeca&amp;quot;,&amp;quot;language&amp;quot;:&amp;quot;Python&amp;quot;,&amp;quot;backend&amp;quot;:&amp;quot;ALEPH_PRECISE&amp;quot;,&amp;quot;code_nav_context&amp;quot;:&amp;quot;BLOB_VIEW&amp;quot;,&amp;quot;retry_backend&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;originating_url&amp;quot;:&amp;quot;https://github.com/leehj01/data-engineering-batch7/find-definition?q=S3ToRedshiftOperator&amp;amp;blob_path=dags%2FMySQL_to_Redshift_v3.py&amp;amp;ref=bafd78d0dd3963bd0946364f8450ed7d944afeca&amp;amp;language=Python&amp;amp;row=3&amp;amp;col=44&amp;amp;code_nav_context=BLOB_VIEW&amp;quot;,&amp;quot;user_id&amp;quot;:65941186}}&quot; data-hydro-click-hmac=&quot;1541a82d247e16ef69d53d9f7b6ee2d4854289460b01b7b894369c85e4bb31b5&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;S3ToRedshiftOperator&lt;/span&gt; 가 존재하기 때문에, operator로 쉽게 이용할 수 도 있어 보였다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span data-hydro-click=&quot;{&amp;quot;event_type&amp;quot;:&amp;quot;code_navigation.click_on_symbol&amp;quot;,&amp;quot;payload&amp;quot;:{&amp;quot;action&amp;quot;:&amp;quot;click_on_symbol&amp;quot;,&amp;quot;repository_id&amp;quot;:469983992,&amp;quot;ref&amp;quot;:&amp;quot;bafd78d0dd3963bd0946364f8450ed7d944afeca&amp;quot;,&amp;quot;language&amp;quot;:&amp;quot;Python&amp;quot;,&amp;quot;backend&amp;quot;:&amp;quot;ALEPH_PRECISE&amp;quot;,&amp;quot;code_nav_context&amp;quot;:&amp;quot;BLOB_VIEW&amp;quot;,&amp;quot;retry_backend&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;originating_url&amp;quot;:&amp;quot;https://github.com/leehj01/data-engineering-batch7/find-definition?q=S3ToRedshiftOperator&amp;amp;blob_path=dags%2FMySQL_to_Redshift_v3.py&amp;amp;ref=bafd78d0dd3963bd0946364f8450ed7d944afeca&amp;amp;language=Python&amp;amp;row=3&amp;amp;col=44&amp;amp;code_nav_context=BLOB_VIEW&amp;quot;,&amp;quot;user_id&amp;quot;:65941186}}&quot; data-hydro-click-hmac=&quot;1541a82d247e16ef69d53d9f7b6ee2d4854289460b01b7b894369c85e4bb31b5&quot;&gt;3. awswrangler&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span data-hydro-click=&quot;{&amp;quot;event_type&amp;quot;:&amp;quot;code_navigation.click_on_symbol&amp;quot;,&amp;quot;payload&amp;quot;:{&amp;quot;action&amp;quot;:&amp;quot;click_on_symbol&amp;quot;,&amp;quot;repository_id&amp;quot;:469983992,&amp;quot;ref&amp;quot;:&amp;quot;bafd78d0dd3963bd0946364f8450ed7d944afeca&amp;quot;,&amp;quot;language&amp;quot;:&amp;quot;Python&amp;quot;,&amp;quot;backend&amp;quot;:&amp;quot;ALEPH_PRECISE&amp;quot;,&amp;quot;code_nav_context&amp;quot;:&amp;quot;BLOB_VIEW&amp;quot;,&amp;quot;retry_backend&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;originating_url&amp;quot;:&amp;quot;https://github.com/leehj01/data-engineering-batch7/find-definition?q=S3ToRedshiftOperator&amp;amp;blob_path=dags%2FMySQL_to_Redshift_v3.py&amp;amp;ref=bafd78d0dd3963bd0946364f8450ed7d944afeca&amp;amp;language=Python&amp;amp;row=3&amp;amp;col=44&amp;amp;code_nav_context=BLOB_VIEW&amp;quot;,&amp;quot;user_id&amp;quot;:65941186}}&quot; data-hydro-click-hmac=&quot;1541a82d247e16ef69d53d9f7b6ee2d4854289460b01b7b894369c85e4bb31b5&quot;&gt;: &lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span data-hydro-click=&quot;{&amp;quot;event_type&amp;quot;:&amp;quot;code_navigation.click_on_symbol&amp;quot;,&amp;quot;payload&amp;quot;:{&amp;quot;action&amp;quot;:&amp;quot;click_on_symbol&amp;quot;,&amp;quot;repository_id&amp;quot;:469983992,&amp;quot;ref&amp;quot;:&amp;quot;bafd78d0dd3963bd0946364f8450ed7d944afeca&amp;quot;,&amp;quot;language&amp;quot;:&amp;quot;Python&amp;quot;,&amp;quot;backend&amp;quot;:&amp;quot;ALEPH_PRECISE&amp;quot;,&amp;quot;code_nav_context&amp;quot;:&amp;quot;BLOB_VIEW&amp;quot;,&amp;quot;retry_backend&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;originating_url&amp;quot;:&amp;quot;https://github.com/leehj01/data-engineering-batch7/find-definition?q=S3ToRedshiftOperator&amp;amp;blob_path=dags%2FMySQL_to_Redshift_v3.py&amp;amp;ref=bafd78d0dd3963bd0946364f8450ed7d944afeca&amp;amp;language=Python&amp;amp;row=3&amp;amp;col=44&amp;amp;code_nav_context=BLOB_VIEW&amp;quot;,&amp;quot;user_id&amp;quot;:65941186}}&quot; data-hydro-click-hmac=&quot;1541a82d247e16ef69d53d9f7b6ee2d4854289460b01b7b894369c85e4bb31b5&quot;&gt;awswrangler 란, &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a style=&quot;font-family: -apple-system, BlinkMacSystemFont, AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot; href=&quot;https://aws.amazon.com/ko/professional-services/&quot;&gt;AWS Professional Services&lt;/a&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;팀에서 개발한&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;font-family: -apple-system, BlinkMacSystemFont, AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot; href=&quot;https://aws-data-wrangler.readthedocs.io/en/stable/index.html&quot;&gt;오픈소스 Python 라이브러리&lt;/a&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;이다. Pandas 라이브러리 기반으로,&amp;nbsp;&lt;/span&gt;데이터를 load/unload 할 수 있는 강력한 기능을 제공한다고, 공식문서에 써있다. 다른 곳에는 못쓰고, AWS 환경에서만 쓸 수 있을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1 ) Connection&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://aws-data-wrangler.readthedocs.io/en/2.4.0-docs/stubs/awswrangler.redshift.connect.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://aws-data-wrangler.readthedocs.io/en/2.4.0-docs/stubs/awswrangler.redshift.connect.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;dataframe을 Redshift에 올리기 위해서,&amp;nbsp; 아래와 같이 코드를 작성했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데, 공식문서에 보이는 것과 같이, connect 파라미터에는 connection 이 존재하는데, 이것은 glue catalog connection 을 의미하는 것이다. 즉, AWS glue 페이지에서 connection 연결을 하고 그 connection 의 이름을 적어주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 glue 의 g 도 건드리지 않는 코드를 사용하는데, 이 aws 모듈 자체가 거기서 정보를 받아오는지 그렇게 해야만 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[ 이런 이유에서인지, airflow로 아래 코드를 사용할때는, glue iam 권한도 부여해줘야 한다. ]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 다른 변수(Boto3)로 접근 할 수도 있으나, 나는 아래의 방법으로 연결하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;connection&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(Optional[str]) &amp;ndash; Glue Catalog Connection name.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;connection = wr.redshift.connect(&quot;redshift_glue_connection&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2 ) to_sql&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://aws-data-wrangler.readthedocs.io/en/1.1.2/stubs/awswrangler.db.to_sql.html#awswrangler.db.to_sql&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://aws-data-wrangler.readthedocs.io/en/1.1.2/stubs/awswrangler.db.to_sql.html#awswrangler.db.to_sql&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 공식 문서의 예제&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import awswrangler as wr
import pandas as pd

&amp;gt;&amp;gt;&amp;gt; wr.db.to_sql(
...     df=pd.DataFrame({'col': [1, 2, 3]}),
...     con=wr.catalog.get_engine(connection=&quot;...&quot;),
...     name=&quot;table_name&quot;,
...     schema=&quot;schema_name&quot;
... )&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&lt;b&gt; 실제 작성 코드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;:&amp;nbsp;&lt;/b&gt;db 대신에 연결하는 db 이름을 적어준다. connection 에는 아래와 같이 코드를 적어주어 연결하였다.&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;connection = wr.redshift.connect(&quot;redshift_glue_connection&quot;)
wr.redshift.to_sql(
    df=mau_df,
    con=connection,
    table=table,
    schema=schema
)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;to_sql 을 사용할 때, 주의할 점은 다 넣고나서, 연결을 닫아 줘야한다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇지 않으면, connection 이 계속 쌓이다가, 고갈된다고 한다.&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;connection.close()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;관련 공식문서&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://aws-data-wrangler.readthedocs.io/en/stable/index.html&quot;&gt;https://aws-data-wrangler.readthedocs.io/en/stable/index.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1649827392750&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Quick Start &amp;mdash; AWS Data Wrangler 2.15.1 documentation&quot; data-og-description=&quot;An AWS Professional Service open source initiative | aws-proserve-opensource@amazon.com Quick Start &amp;gt;&amp;gt;&amp;gt; pip install awswrangler import awswrangler as wr import pandas as pd from datetime import datetime df = pd.DataFrame({&amp;quot;id&amp;quot;: [1, 2], &amp;quot;value&amp;quot;: [&amp;quot;foo&amp;quot;, &amp;quot;bo&quot; data-og-host=&quot;aws-data-wrangler.readthedocs.io&quot; data-og-source-url=&quot;https://aws-data-wrangler.readthedocs.io/en/stable/index.html&quot; data-og-url=&quot;https://aws-data-wrangler.readthedocs.io/en/stable/index.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://aws-data-wrangler.readthedocs.io/en/stable/index.html&quot; data-source-url=&quot;https://aws-data-wrangler.readthedocs.io/en/stable/index.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('&amp;quot;&amp;quot;');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Quick Start &amp;mdash; AWS Data Wrangler 2.15.1 documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;An AWS Professional Service open source initiative | aws-proserve-opensource@amazon.com Quick Start &amp;gt;&amp;gt;&amp;gt; pip install awswrangler import awswrangler as wr import pandas as pd from datetime import datetime df = pd.DataFrame({&quot;id&quot;: [1, 2], &quot;value&quot;: [&quot;foo&quot;, &quot;bo&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;aws-data-wrangler.readthedocs.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;** +) airflow 2.2.2 버전에서, &lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span data-hydro-click=&quot;{&amp;quot;event_type&amp;quot;:&amp;quot;code_navigation.click_on_symbol&amp;quot;,&amp;quot;payload&amp;quot;:{&amp;quot;action&amp;quot;:&amp;quot;click_on_symbol&amp;quot;,&amp;quot;repository_id&amp;quot;:469983992,&amp;quot;ref&amp;quot;:&amp;quot;bafd78d0dd3963bd0946364f8450ed7d944afeca&amp;quot;,&amp;quot;language&amp;quot;:&amp;quot;Python&amp;quot;,&amp;quot;backend&amp;quot;:&amp;quot;ALEPH_PRECISE&amp;quot;,&amp;quot;code_nav_context&amp;quot;:&amp;quot;BLOB_VIEW&amp;quot;,&amp;quot;retry_backend&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;originating_url&amp;quot;:&amp;quot;https://github.com/leehj01/data-engineering-batch7/find-definition?q=S3ToRedshiftOperator&amp;amp;blob_path=dags%2FMySQL_to_Redshift_v3.py&amp;amp;ref=bafd78d0dd3963bd0946364f8450ed7d944afeca&amp;amp;language=Python&amp;amp;row=3&amp;amp;col=44&amp;amp;code_nav_context=BLOB_VIEW&amp;quot;,&amp;quot;user_id&amp;quot;:65941186}}&quot; data-hydro-click-hmac=&quot;1541a82d247e16ef69d53d9f7b6ee2d4854289460b01b7b894369c85e4bb31b5&quot;&gt;awswrangler &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span data-hydro-click=&quot;{&amp;quot;event_type&amp;quot;:&amp;quot;code_navigation.click_on_symbol&amp;quot;,&amp;quot;payload&amp;quot;:{&amp;quot;action&amp;quot;:&amp;quot;click_on_symbol&amp;quot;,&amp;quot;repository_id&amp;quot;:469983992,&amp;quot;ref&amp;quot;:&amp;quot;bafd78d0dd3963bd0946364f8450ed7d944afeca&amp;quot;,&amp;quot;language&amp;quot;:&amp;quot;Python&amp;quot;,&amp;quot;backend&amp;quot;:&amp;quot;ALEPH_PRECISE&amp;quot;,&amp;quot;code_nav_context&amp;quot;:&amp;quot;BLOB_VIEW&amp;quot;,&amp;quot;retry_backend&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;originating_url&amp;quot;:&amp;quot;https://github.com/leehj01/data-engineering-batch7/find-definition?q=S3ToRedshiftOperator&amp;amp;blob_path=dags%2FMySQL_to_Redshift_v3.py&amp;amp;ref=bafd78d0dd3963bd0946364f8450ed7d944afeca&amp;amp;language=Python&amp;amp;row=3&amp;amp;col=44&amp;amp;code_nav_context=BLOB_VIEW&amp;quot;,&amp;quot;user_id&amp;quot;:65941186}}&quot; data-hydro-click-hmac=&quot;1541a82d247e16ef69d53d9f7b6ee2d4854289460b01b7b894369c85e4bb31b5&quot;&gt;을 사용할 때도, 열심히 모듈이 import 가 안되는 문제가 발생하였다..&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span data-hydro-click=&quot;{&amp;quot;event_type&amp;quot;:&amp;quot;code_navigation.click_on_symbol&amp;quot;,&amp;quot;payload&amp;quot;:{&amp;quot;action&amp;quot;:&amp;quot;click_on_symbol&amp;quot;,&amp;quot;repository_id&amp;quot;:469983992,&amp;quot;ref&amp;quot;:&amp;quot;bafd78d0dd3963bd0946364f8450ed7d944afeca&amp;quot;,&amp;quot;language&amp;quot;:&amp;quot;Python&amp;quot;,&amp;quot;backend&amp;quot;:&amp;quot;ALEPH_PRECISE&amp;quot;,&amp;quot;code_nav_context&amp;quot;:&amp;quot;BLOB_VIEW&amp;quot;,&amp;quot;retry_backend&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;originating_url&amp;quot;:&amp;quot;https://github.com/leehj01/data-engineering-batch7/find-definition?q=S3ToRedshiftOperator&amp;amp;blob_path=dags%2FMySQL_to_Redshift_v3.py&amp;amp;ref=bafd78d0dd3963bd0946364f8450ed7d944afeca&amp;amp;language=Python&amp;amp;row=3&amp;amp;col=44&amp;amp;code_nav_context=BLOB_VIEW&amp;quot;,&amp;quot;user_id&amp;quot;:65941186}}&quot; data-hydro-click-hmac=&quot;1541a82d247e16ef69d53d9f7b6ee2d4854289460b01b7b894369c85e4bb31b5&quot;&gt;알고보니, 버전이 안맞아서 그런 것 이었다..ㅠㅠ.. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>DATA ENGINEERING/AWS</category>
      <category>awswrangler</category>
      <category>데이터프레임을 Redshift로 한번에 넣는 방법</category>
      <author>Rmsid01</author>
      <guid isPermaLink="true">https://hazel01.tistory.com/115</guid>
      <comments>https://hazel01.tistory.com/115#entry115comment</comments>
      <pubDate>Wed, 13 Apr 2022 20:43:54 +0900</pubDate>
    </item>
    <item>
      <title>[S3] 파이썬으로 S3에 접근해서, 대용량 데이터 가져오기</title>
      <link>https://hazel01.tistory.com/112</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬 코드로, s3에 있는 대용량 데이터를 가져오는 코드&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;aws에서&amp;nbsp;iam에서&amp;nbsp;만들기&lt;/p&gt;
&lt;pre id=&quot;code_1648178684978&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 필요한 모듈 import 
import boto3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. s3에 접근&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 같은 vpc 나 보안 그룹에 포함되어있는 aws 서버에서는 aws_key 를 입력하지 않아도 되지만, 로컬에서 작업하기 위해서는 아래와 같이 키를 넣어줘야한다. 관련 키 만드는 부분은 다른 글에 정리할 예정이다.&lt;/p&gt;
&lt;pre id=&quot;code_1648178750706&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# s3 에 접근하기 위해서 코드 작성
s3 = boto3.client('s3'
                  ,aws_access_key_id='aws에서 iam에서 만들기'
                  ,aws_secret_access_key='aws에서 iam에서 만들기')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 데이터 가져오기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 그냥 몇개 가져오도록 작업할 수 있지만, 한번에 1000개씩이 아닌, 많은 데이터를 가져오기 위해서는 paginator을 사용해야한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과거에는 아래 코드와 같이 작업을 하였으나, 이제는 get_paginator을 이용해서, list_objects_v2를 사용해야하는 것으로 보인다.&lt;/p&gt;
&lt;pre id=&quot;code_1648178927772&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;object_list = s3.list_objects_v2(**args)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로 작성한 코드이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;paginator을 이용하여 iterator을 만든 이후, for 문을 돌려서 해당 데이터가 있다면 가져오는 식으로 작업한다.&lt;/p&gt;
&lt;pre id=&quot;code_1648178846721&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def get_object_key_list(**args):
    
    keys = []
    # 1000개씩 반환되는 list_objects_v2의 결과 paging처리를 위한 paginator 선언
    paginator = s3.get_paginator(&quot;list_objects_v2&quot;)
    page_iterator = paginator.paginate(**args)

    for page in page_iterator:
        contents = page['Contents']
        for log in contents:
            keys.append(log['Key'])

    return keys&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 데이터를 가져오는 함수를 넣기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;:&amp;nbsp;&lt;/b&gt;위에서 작성한 함수를 실행하면, 아래와 같은 데이터 리스트들이 output으로 나오게 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1648179100770&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;get_object_key_list(Bucket='버킷이름 넣기', Prefix='데이터 위치넣기')&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;749&quot; data-origin-height=&quot;110&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WOIhj/btrxc1UDqLj/OA5GvLsXdFuwV295TgyjJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WOIhj/btrxc1UDqLj/OA5GvLsXdFuwV295TgyjJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WOIhj/btrxc1UDqLj/OA5GvLsXdFuwV295TgyjJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWOIhj%2Fbtrxc1UDqLj%2FOA5GvLsXdFuwV295TgyjJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;749&quot; height=&quot;110&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;749&quot; data-origin-height=&quot;110&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;참고한&amp;nbsp;문서&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;a href=&quot;https://gaussian37.github.io/python-etc-s3_storage_for_boto3/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://gaussian37.github.io/python-etc-s3_storage_for_boto3/&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;amp;blogId=nan17a&amp;amp;logNo=221983762741&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;a href=&quot;https://asecurity.dev/entry/Python-Boto3-lib-paginator-%ED%86%B5%ED%95%9C-S3-%EB%8C%80%EB%9F%89-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://asecurity.dev/entry/Python-Boto3-lib-paginator-%ED%86%B5%ED%95%9C-S3-%EB%8C%80%EB%9F%89-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;a href=&quot;https://gonigoni.kr/posts/list-over-1000-files-from-s3/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://gonigoni.kr/posts/list-over-1000-files-from-s3/&lt;/a&gt;&lt;/p&gt;</description>
      <category>DATA ENGINEERING/AWS</category>
      <category>get_paginator</category>
      <category>S3</category>
      <category>대용량데이터가져오기</category>
      <category>버킷</category>
      <author>Rmsid01</author>
      <guid isPermaLink="true">https://hazel01.tistory.com/112</guid>
      <comments>https://hazel01.tistory.com/112#entry112comment</comments>
      <pubDate>Fri, 25 Mar 2022 12:33:27 +0900</pubDate>
    </item>
    <item>
      <title>[Pyspark 에러] pyspark.sql.utils.AnalysisException: &amp;quot;cannot resolve '`column_name`' given input columns: []</title>
      <link>https://hazel01.tistory.com/111</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;에러 코드&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1647914147351&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Traceback (most recent call last):
  File &quot;/tmp/pycharm_project_578/main.py&quot;, line 115, in &amp;lt;module&amp;gt;
    main()
  File &quot;/tmp/pycharm_project_578/main.py&quot;, line 95, in main
    pv = user_action_df.select(col('metaData.responseTotalCount'))
  File &quot;/usr/lib/spark/python/pyspark/sql/dataframe.py&quot;, line 1320, in select
    jdf = self._jdf.select(self._jcols(*cols))
  File &quot;/usr/lib/spark/python/lib/py4j-src.zip/py4j/java_gateway.py&quot;, line 1257, in __call__
  File &quot;/usr/lib/spark/python/pyspark/sql/utils.py&quot;, line 69, in deco
    raise AnalysisException(s.split(': ', 1)[1], stackTrace)
pyspark.sql.utils.AnalysisException: &quot;cannot resolve '`metaData.responseTotalCount`' given input columns: [metaData.requestFilter.classModelNo,..]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;에러 상황&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Spark DF 의 테이블은 아래와 같이 단순 문자열이 아닌 &amp;lt; . &amp;gt; 이 포함되어있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;837&quot; data-origin-height=&quot;195&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVvD41/btrwJDzlSVh/CXBdxaKKr2lWqAwWeFc0y0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVvD41/btrwJDzlSVh/CXBdxaKKr2lWqAwWeFc0y0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVvD41/btrwJDzlSVh/CXBdxaKKr2lWqAwWeFc0y0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVvD41%2FbtrwJDzlSVh%2FCXBdxaKKr2lWqAwWeFc0y0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;837&quot; height=&quot;195&quot; data-origin-width=&quot;837&quot; data-origin-height=&quot;195&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 위와 같은 테이블에서, 아래와 같은 코드로 특정 컬럼을 select 하려고하니, 에러가 발생하였다.&lt;/p&gt;
&lt;pre id=&quot;code_1647914114293&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pv = user_action_df.select(col('metaData.responseTotalCount'))
print(pv.show())&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;에러 해결&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결방법은 완전 단순하였다.. ` 를 컬럼사이에 넣어주면 된다..ㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저건 어쩔수없이 받아오는 테이블이여서 저렇게 되었지만, 애초에 컬럼이름을 저렇게 작성하지 않는게 좋을것같다.&lt;/p&gt;
&lt;pre id=&quot;code_1647914225200&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pv = user_action_df.select(col('`metaData.responseTotalCount`'))
print(pv.show())&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러 없이 결과 해결 !&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;249&quot; data-origin-height=&quot;195&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAcBbI/btrwJv268y8/SqRsrqQSTYlF0WmIsYRQL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAcBbI/btrwJv268y8/SqRsrqQSTYlF0WmIsYRQL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAcBbI/btrwJv268y8/SqRsrqQSTYlF0WmIsYRQL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAcBbI%2FbtrwJv268y8%2FSqRsrqQSTYlF0WmIsYRQL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;249&quot; height=&quot;195&quot; data-origin-width=&quot;249&quot; data-origin-height=&quot;195&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>DATA  ANALYSIS/PySpark</category>
      <category>annot resolve '`column_name`' given input columns:</category>
      <category>pyspark.sql.utils.AnalysisException</category>
      <category>spark 에러</category>
      <author>Rmsid01</author>
      <guid isPermaLink="true">https://hazel01.tistory.com/111</guid>
      <comments>https://hazel01.tistory.com/111#entry111comment</comments>
      <pubDate>Tue, 22 Mar 2022 10:58:46 +0900</pubDate>
    </item>
  </channel>
</rss>