반응형

04. 판다스 시리즈(Pandas Series) 연산 (min(), max(), mean(), diff(), rank())

1) 기본 코드

import pandas as pd

data1 = [1, 2, 3, 4, 5]
index1 = ['row1', 'row2', 'row3', 'row4', 'row5']

s1 = pd.Series(data=data1, index=index1)

data2 = [6, 7, 8, 9, 10]
index2 = ['row3', 'row4', 'row5', 'row1', 'row2']

s2 = pd.Series(data=data2, index=index2)

sum = s1 + s2

print(sum)
print('max : ' + str(sum.max()))
print('min : ' + str(sum.min()))
print('mean : ' + str(sum.mean()))
print(str(sum.diff(periods=2))
print(sum.rank(ascending=False)) #내림차순
print(sum.rank(ascending=True)) #오름차순

 

반응형

 

 

2) 실행 결과

sum = s1 + s2
print(sum)
row1    10
row2    12
row3     9
row4    11
row5    13
dtype: int64
  • sum = s1 + s2
    • 두개의 Series를 합산
    • 각 Series의 인덱스가 같은 것과 값을 합산
    • 각각의 인덱스 순서가 달라도 합산 가능
print('max : ' + str(sum.max()))
print('min : ' + str(sum.min()))
print('mean : ' + str(sum.mean()))
max : 13
min : 9
mean : 11.0
  • sum이란 Series에서 최대값, 최솟값, 평균값을 출력
print('Diff')
print(sum.diff(periods=2))
Diff
row1    NaN
row2    NaN
row3   -1.0
row4   -1.0
row5    4.0
dtype: float64
  • 값의 차이를 출력
  • periods=2
    • ex) ‘row1’과 ‘row3’의 값 차이를 ‘row3’에 출력
    • ‘row1’, ‘row2’는 비교할 값이 없으므로 NaN으로 출력
print(sum.rank(ascending=False)) #내림차순

print(sum.rank(ascending=True)) #오름차순
row1    4.0
row2    2.0
row3    5.0
row4    3.0
row5    1.0
dtype: float64

row1    2.0
row2    4.0
row3    1.0
row4    3.0
row5    5.0
dtype: float64
  • 내림차순
    • sum.rank(ascending=False)
  • 오름차순
    • sum.rank(ascending=True)
반응형
반응형

03. 판다스 시리즈(Pandas Series) Values 수정, 삭제

1) 기본 코드

import pandas as pd

data = [1,2,3,4,5]
index = ['row1', 'row2', 'row3', 'row4', 'row5']

s = pd.Series(data=data, index=index)


#값 수정 방법
s.iloc[0] = 10
s.loc['row2'] = 20
s[2] = 30
s['row4'] = 40

print(s)
print(s.drop('row5'))
print(s)

 

반응형

 

2) 실행 결과

s.iloc[0] = 10
s.loc['row2'] = 20
s[2] = 30
s['row4'] = 40
print(s)
row1    10
row2    20
row3    30
row4    40
row5     5
dtype: int64
  • 각 인덱스에 접근하여 일반 변수와 같이 값을 할당
  • 한번에 여러 값 변경도 가능
    • ex) s.iloc[0:5] = 10
      1행 부터 5행 까지 값이 모두 10으로 수정
print(s.drop('row5'))
row1    10
row2    20
row3    30
row4    40
dtype: int64
  • 해당 값을 제외하고 값을 출력
  • 인덱스의 명칭(위의 ‘row5’)을 넣어야 함
  • s라는 Series에서 ‘row5’를 빼고 출력하는 것일 뿐 삭제하는 것은 아님
print(s)
row1    10
row2    20
row3    30
row4    40
row5     5
dtype: int64
  • s.drop(’row5’)실행 후 다시 print(s)를 실행해도 row5가 남아있는 것을 볼 수 있음
  • drop은 삭제가 아니라 제외하고 출력
반응형
반응형

02. 판다스 시리즈(Pandas Series) 인덱싱 / 슬라이싱

1) 기본코드

import pandas as pd

data = [1,2,3,4,5]
index = ['row1', 'row2', 'row3', 'row4', 'row5']

s = pd.Series(data=data, index=index)

#출력1
print(s.iloc[0])
print(s.loc['row1'])

#출력2
print(s.iloc[0:3])
print(s.loc['row1':'row3'])

#출력3
print(s.iloc[[0,2]])
print(s.loc[['row1', 'row3']])
  • iloc / loc 차이
  • iloc[int]
    • 숫자로 인덱싱
      • 0,1,2....와 -1,-2... 음수도 가능
    • loc[String]
      • 문자열로 인덱싱
      • 인덱스의 값을 기준으로 인덱싱
print(s.iloc[0])
print(s.loc['row1'])
1
1
  • print(s.iloc[0])
    • 첫번재 행의 값 출력
  • print(s.loc[’row1’])
    • 인덱스값 ‘row1’의 값 출력
print(s.iloc[0:3])
print()
print(s.loc['row1':'row3'])
row1    1
row2    2
row3    3
dtype: int64

row1    1
row2    2
row3    3
dtype: int64
  • print(s.iloc[0:3])
    • 0:3번째 데이터 출력
  • print(s.loc['row1':'row3'])
    • 인덱스 문자열 ‘row1’부터 ‘row3’까지의 값 출력
반응형
print(s.iloc[[0,2]])
print()
print(s.loc[['row1', 'row3']])
row1    1
row3    3
dtype: int64

row1    1
row3    3
dtype: int64
  • print(s.iloc[[0,2]])
    • 0, 2번째 데이터 출력
  • print(s.loc[['row1', 'row3']])
    • 인덱스 문자열 ‘row1’, ‘row3’의 값 출력
반응형
반응형

1. 시리즈(Series) 기본 사용법

1) 기본 코드

import pandas as pd

data = [1,2,3]
index = ['row1', 'row2', 'row3']

s = pd.Series(data=data, index=index)

print(s)

print(s * 10)

print(s.index)

print(s.values)

2) 실행결과

print(s)
row1    1
row2    2
row3    3
dtype: int64
  • 첫열은 인덱스 값(미 설정시 0,1,2....로 자동 지정)
  • 두번재 열은 값
  • dtype : 두번째 열의 데이터 타입
  • Series는 일차원 배열이므로 열 추가가 불가
print(s * 10)
print('\n')
print([1,2,3] * 5)
row1    10
row2    20
row3    30
dtype: int64


[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
  • padas Series는 각 행의 값에 10을 곱한 값을 출력
  • 2번째 파이썬 리스트의 경우 [1,2,3]을 10번 반복해서 출력
print(s.index)
Index(['row1', 'row2', 'row3'], dtype='object')
  • 인덱스 값만 출력
print(s.values)
[1 2 3]
  • 값만 출력
반응형
반응형

1. 판다스(Pandas)

  1. 데이터 분석에 많이 사용되는 파이썬 라이브러리
  2. 기존 파이썬의 리스트 배열이 아닌 판다스 자체적인 자료 구조를 사용
  3. 판다스 시리즈(pandas Series)를 통한 일차원 데이터 관리에 유용
  4. 판다스 데이터프레임(pandas DataFrame)을 통한 이차원 데이터 관리에 유용
  5. 공식 페이지
    https://pandas.pydata.org/
 

pandas - Python Data Analysis Library

pandas pandas is a fast, powerful, flexible and easy to use open source data analysis and manipulation tool, built on top of the Python programming language. Install pandas now!

pandas.pydata.org

 

반응형
반응형

1. 닷넷 스프레드 라이브러리 ReoGrid

  1) ReoGrid https://reogrid.net/  

 

ReoGrid - .NET Spreadsheet Component

Excel Compatibility Loading and saving Excel format, including style, format, drawings and charts. Learn More »

reogrid.net

 

 

 

2. 특징

  1) 무료다 (MIT License)

    (1) 상업용(기업용) 무료

    (2) 기타 상세 내용 링크 https://namu.wiki/w/MIT%20%ED%97%88%EA%B0%80%EC%84%9C

 

  2) 엑셀과 유사한 형태의 UI 컨트롤이다

    (1) 엑셀과 같은 워크 시트탭 기능

    (2) 각종 함수 사용이 가능

    (3) 디테일한 세팅이 가능

3. 단점

  1) 일부 기능 지원 문제

    (1) WPF에서 DropDownList기능 사용 불가

  2) 업데이트 문제

    (1) Github에서 이슈 토론은 이어지나 업데이트 소식은 없음 

반응형
반응형
  1. 프로젝트 목표
    1. 숫자 야구 게임 만들기
    2. MaskedTextBox를 이용하여 원하는 데이터만 받기
    3. 중복되지 않는 난수(Random) 만들기
  2. 프로젝트 내용 
    1. 게임 방법
      1. 게임 시작을 하면 플레이어가 알지 못하게 4자리의 난수를 생성(= 문제 숫자, qNum)
        1. 난수는 0~9로 각기 다른 숫자로 구성
      2. 플레이어는 9번의 기회동안 숫자를 입력하여 문제 숫자를 맞추면 승리
      3. 숫자와 위치 둘다 맞추면 1Strike, 숫자는 맞추되 위치를 틀리면 1ball
    2. 주요 사항
      1. 난수 4자리를 각기 다른 숫자로 구성할 것
        1. 각 자리의 중복 확인 구조를 넣을 것
      2. 입력받는 값은 4자리의 숫자일 것
        1. 윈폼의 MaskedTextBox를 이용하여 원하는 값만 받아 처리
  3. 전체 코드
    1. using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.Data;
      using System.Drawing;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      using System.Windows.Forms;
      
      namespace Number_Baseball
      {
          public partial class Form1 : Form
          {
      
              public string qNum;
              public Boolean gameStartFlag;
              public int try_Count;
              int strikeCount = 0;
              int ballCount = 0;
              public Form1()
              {
                  InitializeComponent();
      
                  gameStartFlag = false;
      
              }
      
              private void btn_Start_Click(object sender, EventArgs e)
              {
                  //문제 숫자 만들기
                  Random rd = new Random();
                  string tempNum = "";
                  bool flag = true;
                  int cc = 0;
      
      
                  //문제 숫자4자리의 중복 제거
                  while(flag)
                  {
                      tempNum = "";
                      for(int k=0; k<4; k++)
                      {
                          tempNum += rd.Next(0, 10).ToString();
                      }
                      Console.WriteLine(tempNum);
                      cc = 0;
                      for (int i = 0; i < 4; i++)
                      {
                          for (int j = 0; j < 4; j++)
                          {
                              if (tempNum[i] == tempNum[j])
                              {
                                  cc += 1;
                              }
                          }
                      }
                      if(cc == 4)
                      {
                          flag = false;
                      }
      
                  }
                  qNum = tempNum;
      
      
                  gameStartFlag = true;
                  try_Count = 0;
      
                  //Try Label 초기화
                  label_Num1.Text = "----";
                  label_Num2.Text = "----";
                  label_Num3.Text = "----";
                  label_Num4.Text = "----";
                  label_Num5.Text = "----";
                  label_Num6.Text = "----";
                  label_Num7.Text = "----";
                  label_Num8.Text = "----";
                  label_Num9.Text = "----";
      
                  //Result Label 초기화
                  label_Result1.Text = "----";
                  label_Result2.Text = "----";
                  label_Result3.Text = "----";
                  label_Result4.Text = "----";
                  label_Result5.Text = "----";
                  label_Result6.Text = "----";
                  label_Result7.Text = "----";
                  label_Result8.Text = "----";
                  label_Result9.Text = "----";
      
                  //숫자 입력창 입력 제한 해제
                  maskedtxt_Try.ReadOnly = false;
                  //숫자 입력창 마스크 형식 설정(0은 정수만 가능한 자리수 표시)
                  maskedtxt_Try.Mask = "0000";
      
              }
      
              private void btn_Retire_Click(object sender, EventArgs e)
              {
                  qNum = "";
                  MessageBox.Show("Sorry about that...");
                  gameStartFlag = false;
              }
      
              private void btn_send_Click(object sender, EventArgs e)
              {
                  string tryNum;
                  tryNum = maskedtxt_Try.Text;
      
                  try_Count += 1;
                  string name = "label_Result" + try_Count.ToString();
                  Control ctnResult = this.Controls[name];
                  string name2 = "label_Num" + try_Count.ToString();
                  Control ctnNum = this.Controls[name2];
                  
                  strikeCount = 0;
                  ballCount = 0;
      
                  if (gameStartFlag == true)
                  {
                      if (maskedtxt_Try.MaskCompleted)
                      {
                          compareCheck(tryNum, qNum);
      
                          ctnNum.Text = tryNum;
                          ctnResult.Text = strikeCount + " S  " + ballCount + " B";
                      }
                      else
                      {
                          MessageBox.Show("Enter the number!");
                          try_Count -= 1;
                      }
                  }
                  else
                  {
                      MessageBox.Show("Please Press Start Button.");
                      Console.WriteLine("3");
                  }
      
                  maskedtxt_Try.Clear();
      
                  if(strikeCount == 4)
                  {
                      MessageBox.Show("You Win");
                  }
                  else if(try_Count == 9 && strikeCount != 4)
                  {
                      MessageBox.Show("You Lose");
                  }
              }
      
              public void compareCheck(string a, string b)
              {
                  for (int k = 0; k < 4; k++)
                  {
                      if (a[k] == b[k])
                      {
                          strikeCount += 1;
                      }
                  }
      
                  for (int i=0; i<4; i++)
                  {
                      for(int j=0; j<4; j++)
                      {
                          if(a[i] == b[j])
                          {
                              ballCount += 1;
                          }
                      }
                  }
                  ballCount -= strikeCount;
              }
          }
      }
  4. 윈폼 화면 구성
  5. Check Point
    1.  MaskedTextBox
      1. 일반적인 텍스트 박스(TextBox, RichTextBox등)과 다르게 프로그래머가 원하는 형식, 값만 사용자가 작성 가능하다.
      2. 위의 코드중 95번째줄을 보면 마스크 설정을 한 것을 알 수 있다.
        1. maskedtxt_try.Mask = "0000";
        2. 텍스트박스에 숫자4자리만 들어 갈 수 있도록 설정함 (0이 숫자를, 네개가 네자리를 뜻함)
        3. 관련 자료는 아래 MSDN에서 확인 가능
          1. https://docs.microsoft.com/ko-kr/dotnet/api/system.windows.forms.maskedtextbox.mask?view=net-5.0
    2. random 난수 만들기 (중복 없는 4자리수 만들기)
      1.            while(flag)
                    {
                        tempNum = "";
                        for(int k=0; k<4; k++)
                        {
                            tempNum += rd.Next(0, 10).ToString();
                        }
                        Console.WriteLine(tempNum);
                        cc = 0;
                        for (int i = 0; i < 4; i++)
                        {
                            for (int j = 0; j < 4; j++)
                            {
                                if (tempNum[i] == tempNum[j])
                                {
                                    cc += 1;
                                }
                            }
                        }
                        if(cc == 4)
                        {
                            flag = false;
                        }
                    }
  6. 다운로드
    1. Number_Baseball.exe
      0.01MB
    2. Number_Baseball.zip
      0.05MB
반응형
반응형
  1. 시작하기 전
    1. 앞선 글인 String토픽 생성을 기반으로 작성하였다.
    2. 기존 String전송과 차이점만 적어놓았으므로 처음이라면 아래의 글을 참고 하기 바란다.
      1. ROS2 패키지만들기-1(패키지 생성) (https://hostramus.tistory.com/112)
      2. ROS2 패키지만들기-2(노드생성 publisher) (https://hostramus.tistory.com/113)
      3. ROS2 패키지만들기-3(노드생성 Subscriber) (https://hostramus.tistory.com/114)
      4. ROS2 패키지만들기-4(확인 및 실행) (https://hostramus.tistory.com/115)
  2.  목표
    1. 2개의 정수를 퍼블리시하는 토픽 만들기
    2. std_msgs.msg의 Int8MultiArray 사용해보기
    3. 2개의 정수를 퍼블리시 하기
    4. 2개의 정수를 서브스크라이브하여 합계 계산하기
  3. 퍼블리셔 코드 (Publisher Code)
    import rclpy
    from rclpy import node
    from rclpy.node import Node
    from rclpy.qos import QoSProfile
    from std_msgs.msg import Int8MultiArray
    
    class HelloworldPublisher222(Node):
      def __init__(self):
        super().__init__('helloworld_publisher222')
        qos_profile = QoSProfile(depth=10)
        self.count = 0
        self.helloworld_publisher = self.create_publisher(Int8MultiArray, 'helloworld', qos_profile)
        self.timer = self.create_timer(1, self.publish_helloworld_msg)
    
      def publish_helloworld_msg(self):
        msg = Int8MultiArray()
        msg.data = [self.count, self.count+1]
        self.helloworld_publisher.publish(msg)
        self.get_logger().info('pub22 message: {0}'.format(msg.data))
        self.count += 1
    
    def main(args=None):
      rclpy.init(args=args)
      node = HelloworldPublisher222()
      try:
        rclpy.spin(node)
      except KeyboardInterrupt:
        node.get_logger().info('Keyboard Interrupt (SIGINT)')
      finally:
        node.destroy_node()
        rclpy.shutdown()
    
    if __name__ == '__main__':
      main()
    ​
  4. 코드 분석 (Publisher)
    1. from std_msgs.msg import Int8MultiArray
       
      1. 5행의 메세지 종류를 Int8MultiArray로 import한다.
      2. int8은 8비트정수로 -127~127까지 범위다
      3. int16, int32, int64중 원하는 크기로 사용한다.
    2. self.helloworld_publisher = self.create_publisher(Int8MultiArray, 'helloworld', qos_profile)
      1. 12행의 self.create_publisher에서 퍼블리시 할 형식을 기존 String대신 Int8Multiarray로 설정한다.
      2. 다른 것은 모두 그대로 놔둔다.
    3. msg = Int8MultiArray()
      msg.data = [self.count, self.count+1]
      1. 16행의 msg에 Int8MultiArray 인스턴스를 생성한다.
      2. 17행에서 msg.data의 값을 array형태로 만들어 넣는다.
        1. 여기에서는 count를 사용하였다.
  5. 서브스크라이버 코드 (Subscriber Code)
    import rclpy
    from rclpy.node import Node
    from rclpy.qos import QoSProfile
    from std_msgs.msg import Int8MultiArray
    
    class HelloworldSubscriber222(Node):
      def __init__(self):
        super().__init__('Helloworld_Subscriber222')
        qos_profile = QoSProfile(depth=10)
        self.helloworld_subscriber = self.create_subscription(Int8MultiArray, 'helloworld', self.subscribe_topic_message, qos_profile)
    
      def subscribe_topic_message(self, msg):
        b = msg.data[0]
        c = msg.data[1]
        self.get_logger().info('Receiced message: {0}'.format(msg.data))
        self.get_logger().info(str(b) + " + " + str(c) + " = " + str(b+c))
    
    def main(args=None):
      rclpy.init(args=args)
      node = HelloworldSubscriber222()
      try:
        rclpy.spin(node)
      except KeyboardInterrupt:
        node.get_logger().info('Keyboard Interrupt (SIGINT)')
      finally:
        node.destroy_node()
        rclpy.shutdown()
    
    if __name__ == '__main__':
      main()​
  6.  코드 분석 (Subscriber)
    1. from std_msgs.msg import Int8MultiArray​
       
      1. 4행에서 퍼블리셔와 같이 메세지 형식을 Int8MultiArray로 맞춰서 import한다.
    2. self.helloworld_subscriber = self.create_subscription(Int8MultiArray, 'helloworld', self.subscribe_topic_message, qos_profile)
      1.  10행에서 self.create_subscription에서 Int8MultiArray로 맞춰준다.
    3.   def subscribe_topic_message(self, msg):
          b = msg.data[0]
          c = msg.data[1]
          self.get_logger().info('Receiced message: {0}'.format(msg.data))
          self.get_logger().info(str(b) + " + " + str(c) + " = " + str(b+c))
      1. msg.data는 Array형태이다.
        1. b와 c에 msg.data[0]과 msg.data[1]의 데이터를 받는다.
      2. self.get_logger().info(str(b) + " + " + str(c) + " = " + str(b+c))
        1. self.get_logger().info()는 스트링타입을 인수로 받는다.
        2. 따라서 정수인 b,c를 str()을 이용하여 변환해준다.
  7. 실행
    1. 퍼블리셔 실행 화면
      1. self.count의 값이 array형태로 퍼블리시 되는것이 확인 된다.
      2. 위의 코드상 int8형식이기에 127이 넘어가는 순간 에러가 발생한다.
    2. 서브스크라이버 실행 화면
      1. 서브스크라이버는 받은 데이터(msg.data)를 한번 출력 후에 두 정수의 합계를 출력한다.

 

아래 출처의 내용을 수정 변경하였습니다.

개인적 공부를 위해 올린 글로 공부하실분은 아래 링크의 글을 참고하시기 바랍니다.

출처 : 오로카 카페 (cafe.naver.com/openrt/24450)

  1.  
반응형

+ Recent posts