리눅스

 

 - 리눅스 기본 명령어

cafe.daum.net/flowlife/9A8Q/161

 

리눅스 기본 명령어

vmwarehttps://www.vmware.com/kr.html무료사용 제품VMware Workstation Playerhttps://www.centos.org/vmware에 centos 설치 하기https://jhnyang.tistory.com/280https://www.ubuntu-kr.org/1. 데비안(Debian)Debian은

cafe.daum.net

 - 리눅스 기본 편집기 vi/vim 명령어

inpages.tistory.com/124

 

 - 터미널 명령어 실행

pwd						: 사용자의 경로
ls						: 디렉토리
-l						: 자세히 보기
-a						: 숨김파일 확인
-al						: 숨김파일 자세히 보기
~						: 현재 사용자의 경로
/						: 리눅스의 경로
vi aaa					: 파일 생성
esc						: 입력어 대기화면
i, a					: append
shift + space			: 한영
:q!						: 미저장 종료
:wq						: 저장 후 종료
vi bbb.txt				: 파일 생성
리눅스에선 확장자 X
vi .ccc					: 숨김 파일 생성
.						: 숨김 파일
yy		  				: 복사
p 		  				: 붙여넣기
dd        				: 한줄 지우기
숫자+명령어   				: 명령어 여러번 반복
:set nu   				: 줄 번호 넣기
:set nonu 				: 줄 번호 제거
whoami    				: id 확인
s /home					: id 확인
mkdir kbs 				: 디렉토리 생성
mkdir -p  mbc/sbs 		: 상위 디렉토리 자동 생성
cd 디렉토리명 				: 디렉토리 변경
cd ~  					: home으로
cd .. 					: 상위 디렉토리로 이동
rmdir 디렉토리명   			: 디렉토리 삭제
rm 파일명         			: 파일 삭제
rm -rf kbs      		: 파일 있어도 삭제 가능
touch 파일명      			: 빈 파일 생성
cat 파일명        			: 파일 내용 확인
cat 파일명1 파일명2 			: 파일 내용확인
cp 파일명 디렉토리명/ 			: 파일 복사
cp 파일명 디렉토리명/새파일명 	: rename 파일 복사
mv 파일명 디렉토리        	: 파일 이동
rename 파일명 happy 새파일명 : 파일명 변경
mv 파일명 새파일명 			: 파일명 변경
head -3 파일명 			: 앞에 3줄 확인
tail -3 파일명 			: 뒤에 3줄 확인 
more +10 파일명 			: 
grep "검색어" 파일명 		: 검색
grep "[^A-Z]" 파일명* 		: 해당 파일명을 가진 모든 파일에서 대문자가 아닌 값 검색
whereis java 			: 파일 설치 모든 경로
whichis java 			: 파일 설치 경로
ifconfig				: ip 확인
su - root				: super user 접속
su - hadoop				: hadoop 일반 계정에 접속
useradd tom				: tom 일반 계정 만들기
passwd tom				: tom 일반 계정에 암호설정
exit					: 해당 계정 logout
userdel james			: 계정 삭제(logout상태에서)
rm -rf james			: 잔여 계정목록 삭제
-rwxrw-r--				: user, group, others
chmod u-w test.txt		: 현재 사용자에게 쓰기 권한 제거
chmod u-r test.txt		: 현재 사용자에게 읽기 권한 제거
chmod u+rwx test. extxt	: 현재 사용자에게 읽기/쓰기/excute 권한 추가
./test.txt				: 명령어 실행
chmod 777 test.txt		: 모든 권한 다 주기
chmod 111 test.txt		: excute 권한 다 주기
ls -l					: 목록 확인
rpm -qa					: 설치 목록확인
rpm -qa java*			: java 설치 경로
yum install gimp		: 설치
su -c 'yum install gimp': 설치
su -c 'yum remove gimp'	: 제거

 

 - gimp 설치

yum list gi*			: 특정단어가 들어간 리스트
which gimp				: gimp 설치 여부 확인
ls -a /usr/bin/gimp
yum info gimp			: 패키지 정보
gimp					: 실행
wget https://t1.daumcdn.net/daumtop_chanel/op/20200723055344399.png : 웹상에서 다운로드
wget https://archive.apache.org/dist/httpd/Announcement1.3.txt		: 웹상에서 다운로드

 

- 파일 압축

vi aa
gzip aa					: 압축
gzip -d aa.gz			: 압축해제
bzip2 aa				: 압축
bzip2 -d aa.bz2			: 압축해제
tar cvf	my.tar aa bb	: 파일 묶기
tar xvf my.tar			: 압축 해제
java -version			: 자바 버전 확인
su -					: 관리자 접속
yum update				: 패키지 업데이트
rpm -qa | grep java*	: rpm 사용하여 파일 설치
java					: 자바 실행
javac					: javac 실행
yum remove java-1.8.0-openjdk-headless.x86_64	: 삭제
yum -y install java-11-openjdk-devel			: 패키지 설치
rpm -qa | java			: 설치 확인

 

- 이클립스 다운로드

mkdir work				: 디렉토리 생성
cd work
eclipse.org - download - 탐색기 - 다운로드 - 복사 - work 붙여넣기
tar xvfz eclipse tab키	: 압축해제
cd eclipse/
./eclipse
work -> jsou
open spective - java
Gerneral - Workspace - utf-8
Web  - utf-8
file - new - java project - pro1 / javaSE-11 - Don't create
new - class - test / main
sysout alt /
sum inss

 

- FlashPlayer 설치

get.adobe.com/kr/flashplayer 접속

wget ftp://ftp.pbone.net/mirror/www.mde.djura.org/2007.0/RPMS/FlashPlayer-9.0.31.0-1mde2007.0.i586.rpm

rm -f FlashPlayer-9.0.31.0-1mde2007.0.i586.rpm

chmod 777 FlashPlayer-9.0.31.0-1mde2007.0.i586.rpm

rpm -Uvh --nodeps FlashPlayer*.rpm

 

- putty

putty -> ifconfig의 ip -> open -> 예

 

 - centos rpm

www.leafcats.com/171

 

 - CentOS에 MariaDB 설치

cafe.daum.net/flowlife/HqLk/81

 

 - MySql, MariaDB

cafe.daum.net/flowlife/HqLk/63 에서 다운로드
Build path - Configure Buil - Librarie - classpath - AddExternel JARs - apply

 

 - apache server 다운로드

apache.org 접속
맨아래 Tomcat 클릭
Download / Tomcat 10 클릭
tar.gz (pgp, sha512) 다운로드
터미널 창 접속
ls /~다운로드
cd work
mv ~/다운로드.apach ~~ .gz ./
tar xvfz apache-tomcat-10.0.5.tar.gz
cd apache-tomcat-10.0.5/
cd bin/
pwd
./startup.sh							: 서버 실행
http://localhost:8080/ 접속
./shutdown.sh							: 서버 종료
./catalina.sh run						: 개발자용 서버 실행
http://localhost:8080/ 접속
ctrl + c								: 개발자용 서버 종료
cd conf
ls se*
vi server.xml
cd ~
pwd
eclipse 접속
Dynimic web project 생성
이름 : webpro / Targert runtime -> apache 10 및 work - apache 폴더 연결
webapp에 abc.html 생성.
window - web browser - firefox
내용 작성 후 서버 실행.

 

 - R, R Studio Server 설치 및 기타

cafe.daum.net/flowlife/RlkF/11

 

 - R 설치

su - root
yum install epel-release
yum install dnf-plugins-core
yum config-manager --set-enabled powertools
yum install R
R
a <- 10
a
df <- data.frame(value=rnorm(1000, 1, 1))
head(df)
head(df, 3)
q()

 

 - R studio 설치

wget https://download1.rstudio.org/desktop/fedora28/x86_64/rstudio-1.2.5033-x86_64.rpm
rpm -ivh rstudio-1.2.5033-x86_64.rpm
exit
rstudio
install.packages("ggplot2")
library(ggplot2)
a <- 10
print(a)
print(head(iris, 3))
ggplot(data=iris, aes(x = Petal.Length, y = Petal.Width)) + geom_point()

 

 - R studio 서버

vi /etc/selinux/config
SELINUX=permissive으로 수정
reboot
su - root
vi /etc/selinux/config
cd /usr/lib/firewalld/services/
ls http*
cp http.xml R.xml
vi R.xml
port="8787"으로 수정
firewall-cmd --permanent --zone=public --add-service=R
firewall-cmd --reload
https://www.rstudio.com/products/rstudio/download-server/
redhat/centos
wget https://download2.rstudio.org/server/centos7/x86_64/rstudio-server-rhel-1.4.1106-x86_64.rpm
wget https://download2.rstudio.org/server/fedora28/x86_64/rstudio-server-rhel-1.2.5033-x86_64.rpm

yum install --nogpgcheck rstudio-server-rhel-1.4.1106-x86_64.rpm
systemctl status rstudio-server
systemctl start rstudio-server
http://ip addr:8787/auth-sign-in	: 본인 ip에 접속

useradd testuser
passwd testuser
ls /home

mkdir mbc
cd mbc
ls

 

 - 프로그램 셋팅 : ipython, anaconda

cafe.daum.net/flowlife/RUrO/44

주의 : VmWare를 사용할 때는 Virtual Machine Settings에서 Processors를 2 이상으로 주도록 하자. 

 

- anaconda 설치

www.anaconda.com/products/individual

Download - Linux / 64-Bit (x86) Installer (529 MB) - 링크주소 복사

wget https://repo.anaconda.com/archive/Anaconda3-2020.02-Linux-x86_64.sh
chmod +x Anaconda~~
./Anaconda~~
q
yes
vi .bash_profile		: 파일 수정
=============================================
PATH=$PATH:$HOME/bin
export PATH

# added by Anaconda3 installer
export PATH="/home/hadoop/anaconda3/bin:$PATH"
==============================================
source .bash_profile
python3
conda deactivate     : 가상환경 나오기
source activate base : 가상환경 들어가기
jupyter notebook
jupyter lab
localhost:8888/tree
ctrl + c
y
jupyter notebook --generate-config
python
from notebook.auth import passwd
passwd()     #sha1 값 얻기
quit()
비밀번호 설정
Verify password 복사
vi .jupyter/jupyter_notebook_config.py		: 파일 수정
ctrl + end
==============================================
c.NotebookApp.password =u'       Verify password 붙여넣기		'
==============================================
quit()
vi .jupyter/jupyter_notebook_config.py
su -
cd /usr/lib/firewalld/services/
cp http.xml NoteBook.xml
vi NoteBook.xml
8001포트 설정
:wq
systemctl status firewalld.service           방화벽 서비스 상태 확인  start, stop, enable
firewall-cmd --permanent --zone=public --add-service=NoteBook
firewall-cmd --reload 
jupyter notebook --ip=0.0.0.0 --port=8001 --allow-root
jupyter lab --ip=0.0.0.0 --port=8001 --allow-root
vi .jupyter/jupyter_notebook_config.py
==============================================
c.NotebookApp.open_browser = False
==============================================

 

 - 하둡 ppt

cafe.daum.net/flowlife/RZ23/24

 : 빅데이터 파일을 여러 대의 서버에 분산 저장(HDFS, Hadoop Distributed File Syetem).

 : 각 서버에서 분산병렬 처리.(MapReduce)

 : 하둡은 데이터 수정불가.

 : sale-out 사용.

 

 - Hadoop 싱글노드로 설치 : Centos 기반 (2020년 기준)

cafe.daum.net/flowlife/RZ23/11

 

 - 하둡 설치

conda deactivate	: 가상환경 나오기
java -version		: 자바 버전 확인
ls -al /etc/alternatives/java	: 자바 경로 확인 후 경로 복사
 => /usr/ ~~ .x86_64 복사
https://apache.org/ 접속 => 맨 밑에 hadoop접속 => Download => 
su -				: 관리자 접속
cd /usr/lib/firewalld/services/	: 특정 port 방화벽 해제
cp http.xml hadoop.xml
vi hadoop.xml					: 파일 수정 후 저장(:wq)
==============================================
<?xml version="1.0" encoding="utf-8"?>
<service>
    <short>Hadoop</short>
    <description></description>
    <port protocol="tcp" port="8042"/>    
    <port protocol="tcp" port="9864"/>
    <port protocol="tcp" port="9870"/>
    <port protocol="tcp" port="8088"/>
    <port protocol="tcp" port="19888"/>
</service>
==============================================
firewall-cmd --permanent --zone=public --add-service=hadoop
firewall-cmd --reload
exit
wget http://apache.mirror.cdnetworks.com/hadoop/common/hadoop-3.2.1/hadoop-3.2.1.tar.gz
tar xvzf hadoop-3.2.1.tar.gz
vi .bash_profile
==============================================
# User specific environment and startup programs
export JAVA_HOME=/usr/ ~~ .x86_64 붙여넣기
export HADOOP_HOME=/home/사용자명/hadoop-3.2.1     
PATH=$PATH:$HOME/.local/bin:$HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin  #추가
export PATH
==============================================
source .bash_profile		: .bash_profile을 수정된 내용으로 등록
conda deactivate
ls
cd hadoop-3.2.1/
vi README.txt
vi kor.txt					: 임의 내용 입력
cd etc
cd hadoop
pwd
vi hadoop-env.sh			: 파일 상단에 입력
==============================================
export JAVA_HOME=/usr/ ~~ .x86_64 붙여넣기
==============================================

vi core-site.xml        : 하둡 공통 설정을 기술
==============================================
<configuration>
        <property>
                <name>fs.default.name</name>
                <value>hdfs://localhost:9000</value>
        </property>
      <property>
                 <name>hadoop.tmp.dir</name> 
                       <value>/home/사용자명/hadoop-3.2.1/tmp/</value>
            </property>
</configuration>
==============================================

vi hdfs-site.xml      : HDFS 동작에 관한 설정
==============================================
<configuration>
     <property>
          <name>dfs.replication</name>
          <value>1</value>
     </property>
</configuration>
==============================================

vi yarn-env.sh         : yarn 설정 파일
==============================================
export JAVA_HOME=/usr/ ~~ .x86_64 붙여넣기
==============================================

vi mapred-site.xml      : yarn 설정 파일
==============================================
<configuration>
     <property>
          <name>mapreduce.framework.name</name>
          <value>yarn</value>
     </property>
     <property>
        <name>mapreduce.admin.user.env</name>
        <value>HADOOP_MAPRED_HOME=$HADOOP_COMMON_HOME</value>
    </property>
    <property>
        <name>yarn.app.mapreduce.am.env</name>
        <value>HADOOP_MAPRED_HOME=$HADOOP_COMMON_HOME</value>
    </property>
</configuration>
==============================================

vi yarn-site.xml
==============================================
<configuration>
<!-- Site specific YARN configuration properties -->
     <property>
          <name>yarn.nodemanager.aux-services</name>
          <value>mapreduce_shuffle</value>
     </property>
     <property>
          <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
          <value>org.apache.hadoop.mapred.ShuffleHandler</value>
     </property>
</configuration>
==============================================

cd					: root로 이동
hdfs namenode -format
hadoop version		: 하둡 버전 확인

ssh					: 원격지 시스템에 접근하여 암호화된 메시지를 전송할 수 있는 프로그램
ssh-keygen -t rsa	: ssh 키 생성. enter 3번.
cd .ssh
scp id_rsa.pub /home/사용자명/.ssh/authorized_keys	: 생성키를 접속할 때 사용하도록 복사함. yes
ssh 사용자명@localhost

start-all.sh		: deprecated
start-dfs.sh
start-yarn.sh
mr-jobhistory-daemon.sh start historyserver	: 안해도됨

jps					: 하둡 실행 상태 확인 - NameNode와 DataNode의 동작여부 확인

stop-all.sh			: deprecated
stop-dfs.sh
stop-yarn.sh

 

http://localhost:9870/ 접속 : Summary(HDFS 상태 확인)
http://localhost:8088/ 접속 : All Applications

 

 - Map/Reduce 처리과정

cafe.daum.net/flowlife/RZ23/17

 

 - 워드 카운트

conda deactivate
cd hadoop-3.2.1/
hdfs dfs -mkdir /test
hdfs dfs -ls/test
hdfs dfs -copyFromLocal ./README.txt /test	: 복사
hdfs dfs -cat /test/README.txt
hadoop jar /home/사용자명/hadoop-3.2.1/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.2.1.jar wordcount /test/README.txt /output			: map/reduce 작업 진행.
hdfs dfs -ls /output						: 목록확인
hdfs dfs -cat /output/part-r-00000
hdfs dfs -ls /
hdfs dfs -rm /output/part*					: 파일삭제
hdfs dfs -rm /output/_SUCCESS
hdfs dfs -rmdir /output

hdfs dfs -put ./kor.txt /test
hadoop jar /home/사용자명/hadoop-3.2.1/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.2.1.jar wordcount /test/kor.txt /daumdata
hdfs dfs -get /daumdata/part* happy.txt		: 하둡에서 파일 가져오기
ls
vi happy.txt

 

 - eclipse + hadoop 연동

conda deactivate
start-dfs.sh
start-yarn.sh
jps
http://localhost:9870/ 접속	: Summary(HDFS 상태 확인)
http://localhost:8088/ 접속	: All Applications
eclipse 실행

 

Tensorflow.js 간단한 예

cafe.daum.net/flowlife/S2Ul/27

 

 * abc.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>tensorflow.js sample</title>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.min.js"></script>

    <script type="text/javascript">
    function abc(){
        // 선형회귀 모델 생성
        const model = tf.sequential();
        model.add(tf.layers.dense({units: 1, inputShape: [1]}));
 
        // 학습을 위한 준비 : 손실 함수와 최적화 함수를 설정
        model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});
 
        // 학습 데이터
        const xs = tf.tensor2d([1, 2, 3, 4], [4, 1]);
        const ys = tf.tensor2d([1, 3, 5, 7], [4, 1]);
 
        // 데이터를 사용해서 학습
        model.fit(xs, ys).then(() => {
            // 학습된 모델로 결과 예측값 얻기
            pred = model.predict(tf.tensor2d([5], [1, 1]))
            pred.print()    // console로 출력
  document.write('예측값 : ', pred);
        });
    }
    </script>	
</head>
<body>
    결과는 브라우저의 콘솔로 확인하세요.
   <br>
    <button xxxxxxxxxxxxonclick="abc()">클릭</button>
</body>
</html>

 

propertive - javaSE
프로젝트 생성
hadoop_pro
Java1.8
프로젝트 오른쪽 클릭
Configure - Convert to Maven Project

 

* pom.xml

maven.org

hadoop-common 검색
apache
3.2.1
<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-common</artifactId>
  <version>3.2.1</version>
</dependency>

hadoop-client
apache
3.2.1
<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-client</artifactId>
  <version>3.2.1</version>
</dependency>

hadoop-hdfs
apache
3.2.1
<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-hdfs</artifactId>
  <version>3.2.2</version>
</dependency>

hadoop-mapreduce-client-core
apache
3.2.1
<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-mapreduce-client-core</artifactId>
  <version>3.2.2</version>
</dependency>

 

 - example code download

hadoop.apache.org/

Documentation - 3.2.2

MapReduce
Tutorial
Example: WordCount v1.0 - Source Code

 

src - new - class - pack.WordCount

* WordCount.java

import java.io.IOException;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class WordCount {

  public static class TokenizerMapper
       extends Mapper<Object, Text, Text, IntWritable>{

    private final static IntWritable one = new IntWritable(1);
    private Text word = new Text();

    public void map(Object key, Text value, Context context
                    ) throws IOException, InterruptedException {
      StringTokenizer itr = new StringTokenizer(value.toString());
      while (itr.hasMoreTokens()) {
        word.set(itr.nextToken());
        context.write(word, one);
      }
    }
  }

  public static class IntSumReducer
       extends Reducer<Text,IntWritable,Text,IntWritable> {
    private IntWritable result = new IntWritable();

    public void reduce(Text key, Iterable<IntWritable> values,
                       Context context
                       ) throws IOException, InterruptedException {
      int sum = 0;
      for (IntWritable val : values) {
        sum += val.get();
      }
      result.set(sum);
      context.write(key, result);
    }
  }

  public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
	
	conf.set("fs.default.name", "hdfs://localhost:9000");
	
    Job job = Job.getInstance(conf, "word count");
    job.setJarByClass(WordCount.class);
    job.setMapperClass(TokenizerMapper.class);
    job.setCombinerClass(IntSumReducer.class);
    job.setReducerClass(IntSumReducer.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);
	
    FileInputFormat.addInputPath(job, new Path("hdfs://localhost:9000/test/data.txt"));
    FileOutputFormat.setOutputPath(job, new Path("hdfs://localhost:9000/out1"));
	System.out.println("success");
	
    //FileInputFormat.addInputPath(job, new Path(args[0]));
    //FileOutputFormat.setOutputPath(job, new Path(args[1]));
	
	System.exit(job.waitForCompletion(true) ? 0 : 1);
  }
}
ls
cd hadoop-3.2.1/
vi data.txt
임의 텍스트 입력
hdfs dfs -put data.txt /test
hdfs dfs -get /out1/part* result1.txt
vi result1.txt
vi vote.txt
임의 텍스트 입력
hdfs dfs -put vote.txt /test

src - new - class - pack2.VoteMapper

 

 * VoteMapper.java

import java.util.regex.*;
import org.apache.hadoop.io.IntWritable
import org.apache.hadoop.io.Text
import org.apache.hadoop.mapreduce.Mapper


public class VoteMapper extends Mapper<Object, Text, Text, IntWritable>{
	private final static IntWritable one =  new IntWritable(1);
	private Text word = new Text();
	
	@Override
	public void map(Object ket, Text value, Context context)throws IOException, InterruptedException{
		String str = value.toString();
		System.out.println(str);
		String regex = "홍길동|신기해|한국인";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(str);
		String result = "";
		while(match.find()){
			result += matcher.group() + "";
		}
		StringTokenizer itr = new StringTokenizer(result);
		
		while(itr.hasMoreTokens()){
			word.set(itr.nextToken());
			context.write(word, one);
		}
	}
}

 

src - new - class - pack2.VoteReducer

 

 * VoteReducer.java

public class VoteReducer extends Reducer<Textm IntWritable, Text, IntWritable>{
	private IntWritable result = new IntWritable();
	
	@Override
	public void reduce(Text key, Iterable<IntWritable> values, Context context) throw IOException, InterruptedException{
		int sum = 0;
		for(IntWritable val:values){
			sum += val.get();
		}
		
		result.set(sum);
		context.wrtie(key, result);
	}
}

 

src - new - class - pack2.VoteCount

 

 * VoteCount.java

public class VoteCount{
	public static void main(String[] args) throws Exception{
		Configuration conf = new Configuration();
		conf.set("fs.default.name", "hdfs://localhost:9000");
		
		Job job = Job.getInstance(conf, "vote");
		job.setJarByClass(VoteCount.class);
		job.setMapperClass(VoteMapper.class);
		job.setCombinerClass(VoteReducer.class);
		job.setReducerClass(VoteReducer.class);
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(IntWritable.class);
		
		FileInputFormat.addInputPath(job, new Path("hdfs://localhost:9000/test/vote.txt"));
		FileOutputFormat.setOutputPath(job, new Path("hdfs://localhost:9000/out2"));
		
		System.out.println("end");
		
		System.exit(job.waitForCompletion(true)?0:1);
	}
}

 

hdfs dfs -get /out2/part* result2.txt

'BACK END > Python Library' 카테고리의 다른 글

[Pandas] pandas 정리2 - db, django  (0) 2021.03.02
[MatPlotLib] matplotlib 정리  (0) 2021.03.02
[Pandas] pandas 정리  (0) 2021.02.24
[NumPy] numpy 정리  (0) 2021.02.23

local db

 * db1.py

# sqlite : db 자료 -> DataFrame -> db

import sqlite3

sql = "create table if not exists test(product varchar(10), maker varchar(10), weight real, price integer)"

conn = sqlite3.connect(':memory:')
#conn = sqlite3.connect('mydb.db')
conn.execute(sql)

data = [('mouse', 'samsung', 12.5, 6000), ('keyboard', 'lg', 502.0, 86000)]
stmt = "insert into test values(?, ?, ?, ?)"
conn.executemany(stmt, data)

data1 = ('연필', '모나미', 3.5, 500)
conn.execute(stmt, data1)
conn.commit()

cursor = conn.execute("select * from test")
rows = cursor.fetchall()
for a in rows:
    print(a)
print()
# DataFrame에 저장 1 - cursor.fetchall() 이용
import pandas as pd
#df1 = pd.DataFrame(rows, columns = ['product', 'maker', 'weight', 'price'])
print(*cursor.description)
df1 = pd.DataFrame(rows, columns = list(zip(*cursor.description))[0])
print(df1)
# DataFrame에 저장 2 - pd.read_sql() 이용
df2 = pd.read_sql("select * from test", conn)
print(df2)
print()

print(df2.to_html())
print()
# DataFrame의 자료를 DB로 저장
data = {
    'irum':['신선해', '신기해', '신기한'],
    'nai':[22, 25, 27]
}
frame = pd.DataFrame(data)
print(frame)
print()

conn = sqlite3.connect('test.db')
frame.to_sql('mytable', conn, if_exists = 'append', index = False)
df3 = pd.read_sql("select * from mytable", conn)
print(df3)

cursor.close()
conn.close()

 

교차 테이블(교차표) - 행과 열로 구성된 교차표로 결과(빈도수)를 요약

 * cross_test

import pandas as pd

y_true = pd.Series([2, 0, 2, 2, 0, 1, 1, 2, 2, 0, 1, 2])
y_pred = pd.Series([0, 0, 2, 1, 0, 2, 1, 0, 2, 0, 2, 2])

result = pd.crosstab(y_true, y_pred, rownames=['True'], colnames=['Predicted'], margins=True)
print(result)
'''
Predicted  0  1  2  All
True                   
0          3  0  0    3
1          0  1  2    3
2          2  1  3    6
All        5  2  5   12
'''
# 인구통계 dataset 읽기
des = pd.read_csv('https://raw.githubusercontent.com/pykwon/python/master/testdata_utf8/descriptive.csv') 
print(des.info())

# 5개 칼럼만 선택하여 data frame 생성 
data = des[['resident','gender','age','level','pass']]
print(data[:5])

# 지역과 성별 칼럼 교차테이블 
table = pd.crosstab(data.resident, data.gender)
print(table)

# 지역과 성별 칼럼 기준 - 학력수준 교차테이블 
table = pd.crosstab([data.resident, data.gender], data.level)
print(table)

 

원격 DB 연동

 * db2_remote.py

import MySQLdb
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rc('font', family='malgun gothic')

import csv
import ast
import sys

try:
    with open('mariadb.txt', 'r') as f:
        config = f.read()
except Exception as e:
    print('read err :', e)
    sys.exit()
    
config = ast.literal_eval(config)
print(config)
# {'host': '127.0.0.1', 'user': 'root', 'password': '123', 'database': 'test', 
# 'port': 3306, 'charset': 'utf8', 'use_unicode': True}
try:
    conn = MySQLdb.connect(**config)
    cursor = conn.cursor()
    sql = """
    select jikwon_no, jikwon_name, jikwon_jik, buser_name, jikwon_gen, jikwon_pay
    from jikwon inner join buser
    on jikwon.buser_num = buser.buser_no
    """
    cursor.execute(sql)
    
    for (jikwon_no, jikwon_name, jikwon_jik, buser_name, jikwon_gen, jikwon_pay) in cursor:
        print(jikwon_no, jikwon_name, jikwon_jik, buser_name, jikwon_gen, jikwon_pay)
    # jikwon.csv 파일로 저장
    with open('jikwon.csv', 'w', encoding='utf-8') as fw:
        writer = csv.writer(fw)
        for row in cursor:
            writer.writerow(row)
        print('저장성공')
    # csv 파일 읽기 1
    df1 = pd.read_csv('jikwon.csv', header=None, names = ('번호', '이름', '직급', '부서', '성별', '연봉'))
    print(df1.head(3))
    print(df1.shape)  # (30, 6)
    # csv 파일 읽기 2
    df2 = pd.read_sql(sql, conn)
    df2.columns = ('번호', '이름', '직급', '부서', '성별', '연봉')
    print(df2.head(3))
    '''
           번호   이름  직급   부서 성별    연봉
    0   1  홍길동  이사  총무부  남  9900
    1   2  한송이  부장  영업부  여  8800
    2   3  이순신  과장  영업부  남  7900
    '''
    print('건수 :', len(df2))
    print('건수 :', df2['이름'].count()) # 건수 : 30
    print()
    
    print('직급별 인원 수 :\n', df2['직급'].value_counts())
    print()
    
    print('연봉 평균 :\n', df2.loc[:,'연봉'].sum() / len(df2))
    print('연봉 평균 :\n', df2.loc[:,'연봉'].mean())
    print()
    
    print('연봉 요약 통계 :\n', df2.loc[:,'연봉'].describe())
    print()
    
    print('연봉이 8000이상 : \n', df2.loc[df2['연봉'] >= 8000])
    print()
    
    print('연봉이 5000이상인 영업부 : \n', df2.loc[(df2['연봉'] >= 5000) & (df2['부서'] == '영업부')])
    print()
    
    print('* crosstab')
    ctab = pd.crosstab(df2['성별'], df2['직급'], margins=True)
    print(ctab)
    print()
    
    print('* groupby')
    print(df2.groupby(['성별', '직급'])['이름'].count())
    print()
    
    print('* pivot table')
    print(df2.pivot_table(['연봉'], index=['성별'], columns=['직급'], aggfunc = np.mean))
    print()
    # 시각화 - pie 차트
    # 직급별 연봉 평균
    jik_ypay = df2.groupby(['직급'])['연봉'].mean()
    print(jik_ypay, type(jik_ypay)) # Series
    print(jik_ypay.index)
    print(jik_ypay.values)
    
    plt.pie(jik_ypay,
            labels=jik_ypay.index, 
            labeldistance=0.5,
            counterclock=False,
            shadow=True,
            explode=(0.2, 0, 0, 0.3, 0))
    plt.show()
    
except Exception as e:
    print('process err :', e)
    
finally:
    cursor.close()
    conn.close()

# DataFrame의 자료를 DB로 저장
data = {
    'irum':['tom', 'james', 'john'],
    'nai':[22, 25, 27]
}
frame = pd.DataFrame(data)
print(frame)
print()

# pip install sqlalchemy
# pip install pymysql
from sqlalchemy import create_engine
import pymysql # MySQL Connector using pymysql

pymysql.install_as_MySQLdb()
engine = create_engine("mysql+mysqldb://root:"+"123"+"@Localhost/test", encoding='utf-8')
conn = engine.connect()

# MySQL에 저장하기
# pandas의 to_sql 함수 사용 저장
frame.to_sql(name='mytable', con = engine, if_exists = 'append', index = False)
df3 = pd.read_sql("select * from mytable", conn)
print(df3)

Django

PyDev Django Project 생성

 * Django - Create application - myjikwonapp

 

 = django_use01

 * settings

...

INSTALLED_APPS = [
    
    ...
    
    'myjikwonapp',
]

...

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', 
        'NAME': 'test',                # DB명 : db는 미리 작성되어 있어야 함.       
        'USER': 'root',                # 계정명 
        'PASSWORD': '123',             # 계정 암호           
        'HOST': '127.0.0.1',           # DB가 설치된 컴의 ip          
        'PORT': '3306',                # DBMS의 port 번호     
    }
}

 

 * anaconda prompt

cd C:\work\psou\django_use01
python manage.py inspectdb > aaa.py

 

 * models

from django.db import models

# Create your models here.
class Jikwon(models.Model):
    jikwon_no = models.IntegerField(primary_key=True)
    jikwon_name = models.CharField(max_length=10)
    buser_num = models.IntegerField()
    jikwon_jik = models.CharField(max_length=10, blank=True, null=True)
    jikwon_pay = models.IntegerField(blank=True, null=True)
    jikwon_ibsail = models.DateField(blank=True, null=True)
    jikwon_gen = models.CharField(max_length=4, blank=True, null=True)
    jikwon_rating = models.CharField(max_length=3, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'jikwon'

 

 * Django - Create Migrations - myjikwonapp

 

 * Django - Migrate

 

 * urls

from django.contrib import admin
from django.urls import path
from myjikwonapp import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.MainFunc),
    path('showdata', views.ShowFunc),
]

 

 * views

from django.shortcuts import render
from myjikwonapp.models import Jikwon
import pandas as pd
import matplotlib.pyplot as plt
plt.rc('font', family='malgun gothic')

# Create your views here.
def MainFunc(request):
    return render(request, 'main.html')

def ShowFunc(request):
    #datas = Jikwon.objects.all()         # jikwon table의 모든 데이터 조회
    datas = Jikwon.objects.all().values() # dict type
    #print(datas)                         # <QuerySet [{'jikwon_no': 1, 'jikwon_name': '홍길동', ...
    
    pd.set_option('display.max_columns', 500) # width : 500
    df = pd.DataFrame(datas)
    df.columns = ['사번', '직원명','부서코드', '직급', '연봉', '입사일', '성별', '평점']
    #print(df)
    '''
            사번  직원명  부서코드  직급    연봉         입사일 성별 평점
    0    1  홍길동    10  이사  9900  2008-09-01  남  a
    1    2  한송이    20  부장  8800  2010-01-03  여  b
    2    3  이순신    20  과장  7900  2010-03-03  남  b
    3    4  이미라    30  대리  4500  2014-01-04  여  b
    4    5  이순라    20  사원  3000  2017-08-05  여  b
    '''
    
    # 부서별 급여 합/평균
    buser_group = df['연봉'].groupby(df['부서코드'])
    buser_group_detail = {'sum':buser_group.sum(), 'avg':buser_group.mean()}
    #print(buser_group_detail)
    '''
    {'sum': 부서코드
    10    37900
    20    58900
    30    37300
    40    25050,
    'avg': 부서코드
    10    5414.285714
    20    4908.333333
    30    5328.571429
    40    6262.500000
    }
    '''
    
    # 차트를 이미지로 저장
    bu_result = buser_group.agg(['sum', 'mean'])
    bu_result.plot.bar()
    #bu_result.plot(kind='bar')
    plt.title("부서별 급여 합/평균")
    fig = plt.gcf()
    fig.savefig('django_use01/myjikwonapp/static/images/jik.png')
    
    return render(request, 'show.html', {'msg':'직원정보', 'datas':df.to_html(), 'buser_group':buser_group_detail})

 

 * main.html

<body>
 <h2>메인</h2>
 <a href="showdata">직원정보</a>
</body>

 

 * show.html

<body>
  <h2>{{msg}} (DB -> pandas 이용)</h2>
  {% if datas %}
  {{datas|safe}}
  {% endif %}
  <hr>
  <h2>부서별 급여합</h2>
  총무부 : {{buser_group.sum.10}}<br>
  영업부 : {{buser_group.sum.20}}<br>
  전산부 : {{buser_group.sum.30}}<br>
  관리부 : {{buser_group.sum.40}}<br><br>
  <h2>부서별 급여평균</h2>
  총무부 : {{buser_group.avg.10}}<br>
  영업부 : {{buser_group.avg.20}}<br>
  전산부 : {{buser_group.avg.30}}<br>
  관리부 : {{buser_group.avg.40}}<br><br>
  <img alt="사진" src="/static/images/jik.png" title="차트 1-1">
</body>


 * desc_stat

# 기술 통계
'''
기술통계(descriptive statistics)란 수집한 데이터의 특성을 표현하고 요약하는 통계 기법이다. 
기술통계는 샘플(전체 자료일수도 있다)이 있으면, 그 자료들에 대해  수치적으로 요약정보를 표현하거나, 
데이터 시각화를 한다. 
즉, 자료의 특징을 파악하는 관점으로 보면 된다. 평균, 분산, 표준편차 등이 기술통계에 속한다.
'''

# 도수 분포표
import pandas as pd

frame = pd.read_csv('../testdata/ex_studentlist.csv')
print(frame.head(2))
print(frame.info())
'''
  name sex  age  grade absence bloodtype  height  weight
0  김길동  남자   23      3       유         O   165.3    68.2
1  이미린  여자   22      2       무        AB   170.1    53.0
'''
print('나이\t:', frame['age'].mean())
print('나이\t:', frame['age'].var())
print('나이\t:', frame['age'].std())
print('혈액형\t:', frame['bloodtype'].unique())
print(frame.describe().T)
print()

# 혈액형별 인원수
data1 = frame.groupby(['bloodtype'])['bloodtype'].count()
print('혈액형별 인원수 : ', data1)
'''
혈액형별 인원수 :  bloodtype
A     3
AB    3
B     4
O     5
'''
print()

data2 = pd.crosstab(index = frame['bloodtype'], columns = 'count')
print('혈액형별 인원수 : ', data2)
'''
혈액형별 인원수 :  col_0      count
bloodtype       
A              3
AB             3
B              4
O              5
'''
print()

# 성별, 혈액형별 인원수
data3 = pd.crosstab(index = frame['bloodtype'], columns = frame['sex'])
data3 = pd.crosstab(index = frame['bloodtype'], columns = frame['sex'], margins=True) # 소계
data3.columns = ['남', '여', '행합']
data3.index = ['A', 'AB', 'B', 'O', '열합']
print('성별, 혈액형별 인원수 : ', data3)
'''
성별, 혈액형별 인원수 :      남  여  행합
A   1  2   3
AB  2  1   3
B   3  1   4
O   2  3   5
열합  8  7  15
'''
print()

print(data3/data3.loc['열합','행합'])
print()
'''
           남         여        행합
A   0.066667  0.133333  0.200000
AB  0.133333  0.066667  0.200000
B   0.200000  0.066667  0.266667
O   0.133333  0.200000  0.333333
열합  0.533333  0.466667  1.000000
'''

matplotlib : ploting library. 그래프 생성을 위한 다양한 함수 지원.

 * mat1.py

import numpy as np
import matplotlib.pyplot as plt

plt.rc('font', family = 'malgun gothic')   # 한글 깨짐 방지
plt.rcParams['axes.unicode_minus'] = False # 음수 깨짐 방지

x = ["서울", "인천", "수원"]
y = [5, 3, 7]
# tuple 가능. set 불가능.

plt.xlabel("지역")                 # x축 라벨
plt.xlim([-1, 3])                 # x축 범위
plt.ylim([0, 10])                 # y축 범위
plt.yticks(list(range(0, 11, 3))) # y축 칸 number 지정
plt.plot(x, y)                    # 그래프 생성
plt.show()                        # 그래프 출력

data = np.arange(1, 11, 2)
print(data)    # [1 3 5 7 9]
plt.plot(data) # 그래프 생성
x = [0, 1, 2, 3, 4]
for a, b in zip(x, data):
    plt.text(a, b, str(b)) # 그래프 라인에 text 표시
plt.show()     # 그래프 출력

plt.plot(data)
plt.plot(data, data, 'r')
plt.show()

x = np.arange(10)
y = np.sin(x)
print(x, y)
plt.plot(x, y, 'bo')  # 파란색 o로 표시. style 옵션 적용.
plt.plot(x, y, 'r+')  # 빨간색 +로 표시
plt.plot(x, y, 'go--', linewidth = 2, markersize = 10) # 초록색 o 표시
plt.show()

# 홀드 : 그림 겹쳐 보기
x = np.arange(0, np.pi * 3, 0.1)
print(x)
y_sin = np.sin(x)
y_cos = np.cos(x)
plt.plot(x, y_sin, 'r')     # 직선, 곡선
plt.scatter(x, y_cos)       # 산포도
#plt.plot(x, y_cos, 'b')
plt.xlabel('x축')
plt.ylabel('y축')
plt.legend(['사인', '코사인']) # 범례
plt.title('차트 제목')         # 차트 제목
plt.show()

 

# subplot : Figure를 여러 행열로 분리
x = np.arange(0, np.pi * 3, 0.1)
y_sin = np.sin(x)
y_cos = np.cos(x)

plt.subplot(2, 1, 1)
plt.plot(x, y_sin)
plt.title('사인')

plt.subplot(2, 1, 2)
plt.plot(x, y_cos)
plt.title('코사인')
plt.show()

irum = ['a', 'b', 'c', 'd', 'e']
kor = [80, 50, 70, 70, 90]
eng = [60, 70, 80, 70, 60]
plt.plot(irum, kor, 'ro-')
plt.plot(irum, eng, 'gs--')
plt.ylim([0, 100])
plt.legend(['국어', '영어'], loc = 4)
plt.grid(True)          # grid 추가

fig = plt.gcf()         # 이미지 저장 선언
plt.show()              # 이미지 출력
fig.savefig('test.png') # 이미지 저장

from matplotlib.pyplot import imread
img = imread('test.png') # 이미지 read
plt.imshow(img)          # 이미지 출력
plt.show()


차트의 종류 결정

 * mat2.py

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()             # 명시적으로 차트 영역 객체 선언
ax1 = fig.add_subplot(1, 2, 1) # 1행 2열 중 1열에 표기
ax2 = fig.add_subplot(1, 2, 2) # 1행 2열 중 2열에 표기

ax1.hist(np.random.randn(10), bins=10, alpha=0.9) # 히스토그램 출력 - bins : 구간 수, alpha: 투명도
ax2.plot(np.random.randn(10)) # plot 출력
plt.show()

fig, ax = plt.subplots(nrows=2, ncols=1)
ax[0].plot(np.random.randn(10))
ax[1].plot(np.random.randn(10) + 20)
plt.show()

data = [50, 80, 100, 70, 90]
plt.bar(range(len(data)), data)
plt.barh(range(len(data)), data)
plt.show()

 

data = [50, 80, 100, 70, 90]
err = np.random.randn(len(data))
plt.barh(range(len(data)), data, xerr=err, alpha = 0.6)
plt.show()

plt.pie(data, explode=(0, 0.2, 0, 0, 0), colors = ['yellow', 'blue', 'red'])
plt.show()

 

n = 30
np.random.seed(42)
x = np.random.rand(n)
y = np.random.rand(n)
color = np.random.rand(n)
scale = np.pi * (15 * np.random.rand(n)) ** 2
plt.scatter(x, y, s = scale, c = color)
plt.show()

import pandas as pd
sdata = pd.Series(np.random.rand(10).cumsum(), index = np.arange(0, 100, 10))
plt.plot(sdata)
plt.show()

# DataFrame
fdata = pd.DataFrame(np.random.randn(1000, 4), index = pd.date_range('1/1/2000', periods = 1000),\
                     columns = list('ABCD'))
print(fdata)
fdata = fdata.cumsum()
plt.plot(fdata)
plt.show()


seaborn : matplotlib 라이브러리의 기능을 보완하기 위해 사용

 * mat3.py

import matplotlib.pyplot as plt
import seaborn as sns

titanic = sns.load_dataset("titanic")
print(titanic.info())
print(titanic.head(3))

age = titanic['age']
sns.kdeplot(age) # 밀도
plt.show()

sns.distplot(age) # kdeplot + hist
plt.show()

import matplotlib.pyplot as plt
import seaborn as sns

titanic = sns.load_dataset("titanic")
print(titanic.info())
print(titanic.head(3))

age = titanic['age']
sns.kdeplot(age) # 밀도
plt.show()

sns.relplot(x = 'who', y = 'age', data=titanic)
plt.show()

 

sns.countplot(x = 'class', data=titanic, hue='who') # hue : 카테고리
plt.show()

t_pivot = titanic.pivot_table(index='class', columns='age', aggfunc='size')
print(t_pivot)
sns.heatmap(t_pivot, cmap=sns.light_palette('gray', as_cmap=True), fmt = 'd', annot=True)
plt.show()

import pandas as pd
iris_data = pd.read_csv('../testdata/iris.csv')
print(iris_data.info())
print(iris_data.head(3))
'''
   Sepal.Length  Sepal.Width  Petal.Length  Petal.Width Species
0           5.1          3.5           1.4          0.2  setosa
1           4.9          3.0           1.4          0.2  setosa
2           4.7          3.2           1.3          0.2  setosa
'''

plt.scatter(iris_data['Sepal.Length'], iris_data['Petal.Length'])
plt.xlabel('Sepal.Length')
plt.ylabel('Petal.Length')
plt.show()

cols = []
for s in iris_data['Species']:
    choice = 0
    if s == 'setosa' : choice = 1
    elif s == 'versicolor' : choice = 2
    else: choice = 3
    cols.append(choice)
    
plt.scatter(iris_data['Sepal.Length'], iris_data['Petal.Length'], c = cols)
plt.xlabel('Sepal.Length')
plt.ylabel('Petal.Length')
plt.show()

# pandas의 시각화 기능
print(type(iris_data)) # DataFrame
from pandas.plotting import scatter_matrix 
#scatter_matrix(iris_data, diagonal='hist')
scatter_matrix(iris_data, diagonal='kde')
plt.show()

# seabon
sns.pairplot(iris_data, hue = 'Species', height = 1)
plt.show()

x = iris_data['Sepal.Length'].values
sns.rugplot(x)
plt.show()

sns.kdeplot(x)
plt.show()

# pandas의 시각화 기능
import numpy as np 

df = pd.DataFrame(np.random.randn(10, 3), index = pd.date_range('1/1/2000', periods=10), columns=['a', 'b', 'c'])
print(df)

#df.plot() # 꺽은선
#df.plot(kind= 'bar')
df.plot(kind= 'box')
plt.xlabel('time')
plt.ylabel('data')
plt.show()

df[:5].plot.bar(rot=0)
plt.show()


 * mat4.py

import pandas as pd

tips = pd.read_csv('../testdata/tips.csv')
print(tips.info())
print(tips.head(3))
'''
   total_bill   tip     sex smoker  day    time  size
0       16.99  1.01  Female     No  Sun  Dinner     2
1       10.34  1.66    Male     No  Sun  Dinner     3
2       21.01  3.50    Male     No  Sun  Dinner     3
'''
tips['gender'] = tips['sex'] # sex 칼럼을 gender 칼럼으로 변경
del tips['sex']
print(tips.head(3))
'''
   total_bill   tip smoker  day    time  size  gender
0       16.99  1.01     No  Sun  Dinner     2  Female
1       10.34  1.66     No  Sun  Dinner     3    Male
2       21.01  3.50     No  Sun  Dinner     3    Male
'''
# tip 비율 추가
tips['tip_pct'] = tips['tip'] / tips['total_bill']
print(tips.head(3))
'''
   total_bill   tip smoker  day    time  size  gender   tip_pct
0       16.99  1.01     No  Sun  Dinner     2  Female  0.059447
1       10.34  1.66     No  Sun  Dinner     3    Male  0.160542
2       21.01  3.50     No  Sun  Dinner     3    Male  0.166587
'''

 

tip_pct_group = tips['tip_pct'].groupby([tips['gender'], tips['smoker']]) # 성별, 흡연자별 그륩화
print(tip_pct_group)
print(tip_pct_group.sum())
print(tip_pct_group.max())
print(tip_pct_group.min())

result = tip_pct_group.describe()
print(result)
'''
               count      mean       std  ...       50%       75%       max
gender smoker                             ...                              
Female No       54.0  0.156921  0.036421  ...  0.149691  0.181630  0.252672
       Yes      33.0  0.182150  0.071595  ...  0.173913  0.198216  0.416667
Male   No       97.0  0.160669  0.041849  ...  0.157604  0.186220  0.291990
       Yes      60.0  0.152771  0.090588  ...  0.141015  0.191697  0.710345
print(tip_pct_group.agg('sum'))
print(tip_pct_group.agg('mean'))
print(tip_pct_group.agg('max'))
print(tip_pct_group.agg('min'))

def diffFunc(group):
    diff = group.max() - group.min()
    return diff

result2 = tip_pct_group.agg(['var', 'mean', 'max', diffFunc])
print(result2)
'''
                    var      mean       max  diffFunc
gender smoker                                        
Female No      0.001327  0.156921  0.252672  0.195876
       Yes     0.005126  0.182150  0.416667  0.360233
Male   No      0.001751  0.160669  0.291990  0.220186
       Yes     0.008206  0.152771  0.710345  0.674707
'''
import matplotlib.pyplot as plt
result2.plot(kind = 'barh', title = 'aff fund', stacked = True)
plt.show()

 

 

 

 

 

 

 

 

 

 

 

 

 

 

pandas : 고수준의 자료구조(Series, DataFrame)를 지원

축약연산, 누락된 데이터 처리, Sql Query, 데이터 조작, 인덱싱, 시각화 .. 등 다양한 기능을 제공.

 

1. Series : 일련의 데이터를 기억할 수 있는 1차원 배열과 같은 자료 구조로 명시적인 색인을 갖는다.

 * pdex1.py

 

 Series(순서가 있는 자료형) : series 생성

from pandas import Series
import numpy as np
obj = Series([3, 7, -5, 4])     # int
obj = Series([3, 7, -5, '4'])  # string - 전체가 string으로 변환
obj = Series([3, 7, -5, 4.5])  # float  - 전체가 float으로 변환
obj = Series((3, 7, -5, 4))    # tuple  - 순서가 있는 자료형 사용 가능
obj = Series({3, 7, -5, 4})    # set    - 순서가 없어 error 발생
print(obj, type(obj))
'''
0    3
1    7
2   -5
3    4
dtype: int64 <class 'pandas.core.series.Series'>
'''

 

 Series( , index = ) : 색인 지정

obj2 = Series([3, 7, -5, 4], index = ['a', 'b', 'c', 'd']) # index : 색인 지정
print(obj2)
'''
a    3
b    7
c   -5
d    4
dtype: int64
'''

 

 np.sum(obj2) = obj2.sum()

print(sum(obj2), np.sum(obj2), obj2.sum()) # pandas는 numpy 함수를 기본적으로 계승해서 사용.
'''
9 9 9
'''

 

 obj.values : value를 list형으로 리턴

 obj.index : index를 object형으로 리턴

print(obj2.values) # 값만 출력
print(obj2.index)  # index만 출력
'''
[ 3  7 -5  4]
Index(['a', 'b', 'c', 'd'], dtype='object')
'''

 

슬라이싱

'''
a    3
b    7
c   -5
d    4
'''
print(obj2['a'], obj2[['a']])
# 3 a    3

print(obj2[['a', 'b']])
'''
a    3
b    7
'''
print(obj2['a':'c'])
'''
a    3
b    7
c   -5
'''
print(obj2[2]) # -5
print(obj2[1:4])
'''
b    7
c   -5
d    4
'''
print(obj2[[2,1]])
'''
c   -5
b    7
'''
print(obj2 > 0)
'''
a     True
b     True
c    False
d     True
'''
print('a' in obj2)
# True

 

dict type으로 Series 생성

names = {'mouse':5000, 'keyboard':25000, 'monitor':55000}
print(names)
# {'mouse': 5000, 'keyboard': 25000, 'monitor': 55000}

obj3 = Series(names)
print(obj3, ' ', type(obj3))
'''
mouse        5000
keyboard    25000
monitor     55000
dtype: int64   <class 'pandas.core.series.Series'>
'''
print(obj3['mouse'])
# 5000

obj3.name = '상품가격' # Series 객체에 이름 부여
print(obj3)
'''
mouse        5000
keyboard    25000
monitor     55000
Name: 상품가격, dtype: int64
'''

 

DataFrame : 표 모양(2차원)의 자료 구조. Series가 여러개 합쳐진 형태. 각 칼럼마다 type이 다를 수 있다.

from pandas import DataFrame
df = DataFrame(obj3) # Series로 DataFrame 생성
print(df)
'''
           상품가격
mouse      5000
keyboard  25000
monitor   55000
'''
data = {
    'irum':['홍길동', '한국인', '신기해', '공기밥', '한가해'],
    'juso':['역삼동', '신당동', '역삼동', '역삼동', '신사동'],
    'nai':[23, 25, 33, 30, 35]
    }
print(data, type(data))
'''
{'irum': ['홍길동', '한국인', '신기해', '공기밥', '한가해'],
 'juso': ['역삼동', '신당동', '역삼동', '역삼동', '신사동'],
 'nai': [23, 25, 33, 30, 35]}
 <class 'dict'>
'''
frame = DataFrame(data) # dict로 DataFrame 생성
print(frame)
'''
  irum juso  nai
0  홍길동  역삼동   23
1  한국인  신당동   25
2  신기해  역삼동   33
3  공기밥  역삼동   30
4  한가해  신사동   35
'''
print(frame['irum']) # 칼럼을 dict 형식으로 접근
'''
0    홍길동
1    한국인
2    신기해
3    공기밥
4    한가해
'''
print(frame.irum, ' ', type(frame.irum))    # 칼럼을 속성 형식으로 접근
'''
0    홍길동
1    한국인
2    신기해
3    공기밥
4    한가해
Name: irum, dtype: object
<class 'pandas.core.series.Series'>
'''
print(DataFrame(data, columns=['juso', 'irum', 'nai'])) # 칼럼의 순서변경
'''
  juso irum  nai
0  역삼동  홍길동   23
1  신당동  한국인   25
2  역삼동  신기해   33
3  역삼동  공기밥   30
4  신사동  한가해   35
'''
print()
frame2 = DataFrame(data, columns=['juso', 'irum', 'nai', 'tel'], index = ['a', 'b', 'c', 'd', 'e'])
print(frame2)
'''
  juso irum  nai  tel
a  역삼동  홍길동   23  NaN
b  신당동  한국인   25  NaN
c  역삼동  신기해   33  NaN
d  역삼동  공기밥   30  NaN
e  신사동  한가해   35  NaN
'''
frame2['tel'] = '111-1111' # tel 칼럼의 모든행에 적용
print(frame2)
'''
  juso irum  nai       tel
a  역삼동  홍길동   23  111-1111
b  신당동  한국인   25  111-1111
c  역삼동  신기해   33  111-1111
d  역삼동  공기밥   30  111-1111
e  신사동  한가해   35  111-1111
'''
print()
val = Series(['222-2222', '333-2222', '444-2222'], index = ['b', 'c', 'e'])
frame2['tel'] = val
print(frame2)
'''
  juso irum  nai       tel
a  역삼동  홍길동   23       NaN
b  신당동  한국인   25  222-2222
c  역삼동  신기해   33  333-2222
d  역삼동  공기밥   30       NaN
e  신사동  한가해   35  444-2222

'''
print()
print(frame2.T) # 행과 열 swap
'''
        a         b         c    d         e
juso  역삼동       신당동       역삼동  역삼동       신사동
irum  홍길동       한국인       신기해  공기밥       한가해
nai    23        25        33   30        35
tel   NaN  222-2222  333-2222  NaN  444-2222
'''
print(frame2.values)
'''
[['역삼동' '홍길동' 23 nan]
 ['신당동' '한국인' 25 '222-2222']
 ['역삼동' '신기해' 33 '333-2222']
 ['역삼동' '공기밥' 30 nan]
 ['신사동' '한가해' 35 '444-2222']]
'''
print(frame2.values[0, 1]) # 0행 1열. 홍길동
print(frame2.values[0:2])  # 0 ~ 1행
'''
[['역삼동' '홍길동' 23 nan]
 ['신당동' '한국인' 25 '222-2222']]
'''

 

행/열 삭제

#frame3 = frame2.drop('d')         # index가 d인 행 삭제
frame3 = frame2.drop('d', axis=0) # index가 d인 행 삭제
print(frame3)
'''
  juso irum  nai       tel
a  역삼동  홍길동   23       NaN
b  신당동  한국인   25  222-2222
c  역삼동  신기해   33  333-2222
e  신사동  한가해   35  444-2222
'''
frame3 = frame2.drop('tel', axis = 1) # index가 tel인 열 삭제
print(frame3)
'''
  juso irum  nai
a  역삼동  홍길동   23
b  신당동  한국인   25
c  역삼동  신기해   33
d  역삼동  공기밥   30
e  신사동  한가해   35
'''

 

정렬

print(frame2.sort_index(axis=0, ascending=False)) # 행 단위. 내림차순
'''
  juso irum  nai       tel
e  신사동  한가해   35  444-2222
d  역삼동  공기밥   30       NaN
c  역삼동  신기해   33  333-2222
b  신당동  한국인   25  222-2222
a  역삼동  홍길동   23       NaN
'''
print(frame2.sort_index(axis=1, ascending=True)) # 열 단위. 오름차순
'''
  irum juso  nai       tel
a  홍길동  역삼동   23       NaN
b  한국인  신당동   25  222-2222
c  신기해  역삼동   33  333-2222
d  공기밥  역삼동   30       NaN
e  한가해  신사동   35  444-2222
'''
print(frame2.rank(axis=0)) # 행 단위. 사전 순위로 칼럼 값 순서를 매김
'''
   juso  irum  nai  tel
a   4.0   5.0  1.0  NaN
b   1.0   4.0  2.0  1.0
c   4.0   2.0  4.0  2.0
d   4.0   1.0  3.0  NaN
e   2.0   3.0  5.0  3.0
'''
print(frame2['juso'].value_counts()) # 칼럼의 개수
'''
역삼동    3
신사동    1
신당동    1
'''

 

문자열 자르기

data = {
    'juso':['강남구 역삼동', '중구 신당동', '강남구 대치동'],
    'inwon':[22,23,24]
}
fr = DataFrame(data)
print(fr)
'''
      juso  inwon
0  강남구 역삼동     22
1   중구 신당동     23
2  강남구 대치동     24
'''
result1 = Series([x.split()[0] for x in fr.juso])
result2 = Series([x.split()[1] for x in fr.juso])
print(result1)
'''
0    강남구
1     중구
2    강남구
'''
print(result2)
'''
0    역삼동
1    신당동
2    대치동
'''
print(result1.value_counts())
'''
강남구    2
중구     1
'''

재 색인, NaN, bool처리, 슬라이싱 관련 메소드, 연산

 * pdex2.py

 

Series 재 색인

data = Series([1,3,2], index = (1,4,2))
print(data)
'''
1    1
4    3
2    2
'''

data2 = data.reindex((1,2,4)) # 해당 index 순서로 정렬
print(data2)
'''
1    1
2    2
4    3
'''

 

재색인 시 값 채워 넣기

data3 = data2.reindex([0,1,2,3,4,5]) # 대응 값이 없는 인덱스는 NaN(결측값)이 됨.
print(data3)
'''
0    NaN
1    1.0
2    2.0
3    NaN
4    3.0
5    NaN
'''

data3 = data2.reindex([0,1,2,3,4,5], fill_value = 333) # 대응 값이 없는 인덱스는 fill_value으로 대입.
print(data3)
'''
0    333
1      1
2      2
3    333
4      3
5    333
'''

data3 = data2.reindex([0,1,2,3,4,5], method='ffill') # 대응 값이 없는 인덱스는 이전 index의 값으로 대입.
print(data3)
data3 = data2.reindex([0,1,2,3,4,5], method='pad') # 대응 값이 없는 인덱스는 이전 index의 값으로 대입.
print(data3)
'''
0    NaN
1    1.0
2    2.0
3    2.0
4    3.0
5    3.0
'''

data3 = data2.reindex([0,1,2,3,4,5], method='bfill') # 대응 값이 없는 인덱스는 다음 index의 값으로 대입.
print(data3)
data3 = data2.reindex([0,1,2,3,4,5], method='backfill') # 대응 값이 없는 인덱스는 다음 index의 값으로 대입.
print(data3)
'''
0    1.0
1    1.0
2    2.0
3    3.0
4    3.0
5    NaN
'''

 

bool 처리 / 슬라이싱

df = DataFrame(np.arange(12).reshape(4,3), index=['1월', '2월', '3월', '4월'], columns=['강남', '강북', '서초'])
print(df)
'''
    강남  강북  서초
1월   0   1   2
2월   3   4   5
3월   6   7   8
4월   9  10  11
'''

print(df['강남'])
'''
1월    0
2월    3
3월    6
4월    9
'''

print(df['강남'] > 3 ) # True나 False 반환
'''
1월    False
2월    False
3월     True
4월     True
'''

print(df[df['강남'] > 3] ) # 강남이 3보다 큰 값 월의 값을 출력
'''
    강남  강북  서초
3월   6   7   8
4월   9  10  11
'''

df[df < 3] = 0 # 3보다 작으면 0 대입
print(df)
'''
    강남  강북  서초
1월   0   0   0
2월   3   4   5
3월   6   7   8
4월   9  10  11
'''

print(df.loc['3월', :]) # 복수 indexing. loc : 라벨 지원. iloc : 숫자 지원
print(df.loc['3월', ]) 
# 3월 행의 모든 값을 출력
'''
강남    6
강북    7
서초    8
'''
print(df.loc[:'2월']) # 2월행 이하의 모든 값 출력
'''
    강남  강북  서초
1월   0   0   0
2월   3   4   5
'''
print(df.loc[:'2월',['서초']]) # 2월 이하 서초 열만 출력
'''
    서초
1월   0
2월   5
'''
print(df.iloc[2]) # 2행의 모든 값 출력
print(df.iloc[2, :]) # 2행의 모든 값 출력
'''
강남    6
강북    7
서초    8
'''

print(df.iloc[:3]) # 3행 미만 행 모든 값 출력
'''
    강남  강북  서초
1월   0   0   0
2월   3   4   5
3월   6   7   8
'''
print(df.iloc[:3, 2]) # 3행 미만 행 2열 미만 출력
'''
1월    0
2월    5
3월    8
'''
print(df.iloc[:3, 1:3]) # 3행 미만 행 1~2열 출력
'''
    강북  서초
1월   0   0
2월   4   5
3월   7   8
'''

 

연산

s1 = Series([1,2,3], index = ['a', 'b', 'c'])
s2 = Series([4,5,6,7], index = ['a', 'b', 'd', 'c'])
print(s1)
'''
a    1
b    2
c    3
'''
print(s2)
'''
a    4
b    5
d    6
c    7
'''

print(s1 + s2) # 인덱스가 값은 경우만 연산, 불일치시 NaN
print(s1.add(s2))
'''
a     5.0
b     7.0
c    10.0
d     NaN
'''

df1 = DataFrame(np.arange(9).reshape(3,3), columns=list('kbs'), index=['서울', '대전', '부산'])
print(df1)
'''
    k  b  s
서울  0  1  2
대전  3  4  5
부산  6  7  8
'''

df2 = DataFrame(np.arange(12).reshape(4,3), columns=list('kbs'), index=['서울', '대전', '제주', '수원'])
print(df2)
'''
    k   b   s
서울  0   1   2
대전  3   4   5
제주  6   7   8
수원  9  10  11
'''

print(df1 + df2) # 대응되는 index만 연산
print(df1.add(df2))
'''
      k    b     s
대전  6.0  8.0  10.0
부산  NaN  NaN   NaN
서울  0.0  2.0   4.0
수원  NaN  NaN   NaN
제주  NaN  NaN   NaN
'''
print(df1.add(df2, fill_value = 0)) # 대응되지않는 값은 0으로 대입 후 연산
'''
      k     b     s
대전  6.0   8.0  10.0
부산  6.0   7.0   8.0
서울  0.0   2.0   4.0
수원  9.0  10.0  11.0
제주  6.0   7.0   8.0
'''

seri = df1.iloc[0] # 0행만 추출
print(seri)
'''
k    0
b    1
s    2
'''

print(df1)
'''
    k  b  s
서울  0  1  2
대전  3  4  5
부산  6  7  8
'''

print(df1 - seri)
'''
    k  b  s
서울  0  0  0
대전  3  3  3
부산  6  6  6
'''

 

 함수

df = DataFrame([[1.4, np.nan], [7, -4.5], [np.NaN, np.NaN, None], [0.5, -1]]) # , index=['one', 'two', 'three', 'four']
print(df)
'''
     0    1     2
0  1.4  NaN  None
1  7.0 -4.5  None
2  NaN  NaN  None
3  0.5 -1.0  None
'''
print(df.isnull()) # null 여부 확인
'''
       0      1     2
0  False   True  True
1  False  False  True
2   True   True  True
3  False  False  True
'''
print(df.notnull())
'''
       0      1      2
0   True  False  False
1   True   True  False
2  False  False  False
3   True   True  False
'''
print(df.drop(1)) # 행 삭제
'''
     0    1     2
0  1.4  NaN  None
2  NaN  NaN  None
3  0.5 -1.0  None
'''
print()
print(df.dropna()) # na가 포함된 행 삭제
'''
Empty DataFrame
Columns: [0, 1, 2]
Index: []
'''
print()
print(df.dropna(how='any')) # na가 포함된 행 삭제
'''
Empty DataFrame
Columns: [0, 1, 2]
Index: []
'''
print(df.dropna(how='all')) # 모든 값이 na인 행 삭제
'''
     0    1     2
0  1.4  NaN  None
1  7.0 -4.5  None
3  0.5 -1.0  None
'''
print(df.dropna(axis='rows')) # na가 포함된 행 삭제
'''
Empty DataFrame
Columns: [0, 1, 2]
Index: []
'''
print(df.dropna(axis='columns')) # na가 포함된 열 삭제
'''
Empty DataFrame
Columns: []
Index: [0, 1, 2, 3]
'''
print(df.fillna(0)) # na를 0으로 채움
'''
     0    1  2
0  1.4  0.0  0
1  7.0 -4.5  0
2  0.0  0.0  0
3  0.5 -1.0  0
'''
#print(df.dropna(subset = ['one']))
print(df)
print('--------')
print(df.sum()) # 열 단위 합
print(df.sum(axis = 0)) # 열 단위 합
'''
0    8.9
1   -5.5
2    0.0
'''
print(df.sum(axis = 1)) # 행 단위 합
'''
0    1.4
1    2.5
2    0.0
3   -0.5
'''
print(df.mean(axis = 1)) # 행단위 평균
'''
0    1.40
1    1.25
2     NaN
3   -0.25
'''
print(df.mean(axis = 1, skipna= False)) # 행단위 평균
'''
0     NaN
1    1.25
2     NaN
3   -0.25
'''
print(df.mean(axis = 1, skipna= True)) # 행단위 평균
'''
0    1.40
1    1.25
2     NaN
3   -0.25
'''
print()
print(df.describe()) # 요약 통계량
'''
              0         1
count  3.000000  2.000000
mean   2.966667 -2.750000
std    3.521837  2.474874
min    0.500000 -4.500000
25%    0.950000 -3.625000
50%    1.400000 -2.750000
75%    4.200000 -1.875000
max    7.000000 -1.000000
'''
print(df.info()) # 구조확인
'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 3 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   0       3 non-null      float64
 1   1       2 non-null      float64
 2   2       0 non-null      object 
dtypes: float64(2), object(1)
memory usage: 224.0+ bytes
None
'''
print()
words = Series(['봄', '여름', '가을', '봄'])
print(words.describe())
'''
count     4
unique    3
top       봄
freq      2
dtype: object
'''
#print(words.info()) #AttributeError: 'Series' object has no attribute 'info'

구조 : stack, unstack, cut, merge, concat, pivot

 

* pdex3.py

import pandas as pd
import numpy as np

df = pd.DataFrame(1000 + np.arange(6).reshape(2, 3), index=['대전', '서울'],\
                   columns = ['2019', '2020', '2021'])
print(df)
'''
    2019  2020  2021
대전  1000  1001  1002
서울  1003  1004  1005
'''
#print(df.info()) # 정보 보기
print()

df_row = df.stack() # 칼럼을 기준으로 stack 구조로 변경
print(df_row)
'''
대전  2019    1000
    2020    1001
    2021    1002
서울  2019    1003
    2020    1004
    2021    1005
'''
df_col = df_row.unstack()
print(df_col)
'''
    2019  2020  2021
대전  1000  1001  1002
서울  1003  1004  1005
'''

 

범주화

price = [10.3, 5.5, 7.8, 3.6] # data
cut = [3, 7, 9, 11] # 범주
result_cut = pd.cut(price, cut) # data를 범주 기준으로 나눠 범주화 진행. 
print(result_cut)
'''
[(9, 11], (3, 7], (7, 9], (3, 7]]
Categories (3, interval[int64]): [(3, 7] < (7, 9] < (9, 11]]
'''

print(pd.value_counts(result_cut)) # value의 수
'''
(3, 7]     2
(9, 11]    1
(7, 9]     1
'''
print()

datas = pd.Series(np.arange(1, 1001))
print(datas.head(3))
'''
0    1
1    2
2    3
'''
print(datas.tail(4))
'''
996     997
997     998
998     999
999    1000
'''
result_cut2 = pd.cut(datas, 3)
print(result_cut2)
'''
0       (0.001, 334.0]
1       (0.001, 334.0]
2       (0.001, 334.0]
3       (0.001, 334.0]
4       (0.001, 334.0]
            ...       
995    (667.0, 1000.0]
996    (667.0, 1000.0]
997    (667.0, 1000.0]
998    (667.0, 1000.0]
999    (667.0, 1000.0]
Length: 1000, dtype: category
Categories (3, interval[float64]): [(0.001, 334.0] < (334.0, 667.0] < (667.0, 1000.0]]
'''
print(pd.value_counts(result_cut2))
'''
(0.001, 334.0]     334
(667.0, 1000.0]    333
(334.0, 667.0]     333
'''

 

merge

df1 = pd.DataFrame({'data1':range(7), 'key':['b', 'b', 'a', 'c', 'a', 'a', 'b']})
print(df1)
'''
   data1 key
0      0   b
1      1   b
2      2   a
3      3   c
4      4   a
5      5   a
6      6   b
'''
df2 = pd.DataFrame({'key':['a', 'b', 'd'], 'data2':range(3)})
print(df2)
'''
  key  data2
0   a      0
1   b      1
2   d      2
'''
print()

print(pd.merge(df1, df2)) # inner join
print(pd.merge(df1, df2, on = 'key')) # inner join
print(pd.merge(df1, df2, on = 'key', how = 'inner')) # inner join
'''
   data1 key  data2
0      0   b      1
1      1   b      1
2      6   b      1
3      2   a      0
4      4   a      0
5      5   a      0
'''

print(pd.merge(df1, df2, on = 'key', how = 'outer')) # full outer join
'''
   data1 key  data2
0    0.0   b    1.0
1    1.0   b    1.0
2    6.0   b    1.0
3    2.0   a    0.0
4    4.0   a    0.0
5    5.0   a    0.0
6    3.0   c    NaN
7    NaN   d    2.0
'''
print(pd.merge(df1, df2, on = 'key', how = 'left')) # left outer join
'''
   data1 key  data2
0      0   b    1.0
1      1   b    1.0
2      2   a    0.0
3      3   c    NaN
4      4   a    0.0
5      5   a    0.0
6      6   b    1.0
'''
print(pd.merge(df1, df2, on = 'key', how = 'right')) # right outer join
'''
   data1 key  data2
0    2.0   a      0
1    4.0   a      0
2    5.0   a      0
3    0.0   b      1
4    1.0   b      1
5    6.0   b      1
6    NaN   d      2
'''

공통 칼럼명이 없는 경우

df3 = pd.DataFrame({'key2':['a','b','d'], 'data2':range(3)})
print(df3)
'''
  key2  data2
0    a      0
1    b      1
2    d      2
'''

print(df1)
'''
   data1 key
0      0   b
1      1   b
2      2   a
3      3   c
4      4   a
5      5   a
6      6   b
'''

print(pd.merge(df1, df3, left_on = 'key', right_on = 'key2'))
'''
   data1 key key2  data2
0      0   b    b      1
1      1   b    b      1
2      6   b    b      1
3      2   a    a      0
4      4   a    a      0
5      5   a    a      0
'''
print()
print(pd.concat([df1, df3]))
print(pd.concat([df1, df3], axis = 0)) # 열 단위
'''
   data1  key key2  data2
0    0.0    b  NaN    NaN
1    1.0    b  NaN    NaN
2    2.0    a  NaN    NaN
3    3.0    c  NaN    NaN
4    4.0    a  NaN    NaN
5    5.0    a  NaN    NaN
6    6.0    b  NaN    NaN
0    NaN  NaN    a    0.0
1    NaN  NaN    b    1.0
2    NaN  NaN    d    2.0
'''

print(pd.concat([df1, df3], axis = 1)) # 행 단위
'''
   data1 key key2  data2
0      0   b    a    0.0
1      1   b    b    1.0
2      2   a    d    2.0
3      3   c  NaN    NaN
4      4   a  NaN    NaN
5      5   a  NaN    NaN
6      6   b  NaN    NaN
'''

 

피벗 테이블: 데이터의 행렬을 재구성하여 그륩화 처리

data = {'city':['강남', '강북', '강남', '강북'],
        'year':[2000, 2001, 2002, 2002],
        'pop':[3.3, 2.5, 3.0, 2]
        }
df = pd.DataFrame(data)
print(df)
'''
  city  year  pop
0   강남  2000  3.3
1   강북  2001  2.5
2   강남  2002  3.0
3   강북  2002  2.0
'''

print(df.pivot('city', 'year', 'pop')) # city별, year별 pop의 평균
print(df.set_index(['city', 'year']).unstack()) # 기존의 행 인덱스를 제거하고 첫번째 열 인덱스 설정 
'''
year  2000  2001  2002
city                  
강남     3.3   NaN   3.0
강북     NaN   2.5   2.0
'''
print(df.pivot('year', 'city', 'pop')) # year별 , city별 pop의 평균
'''
city   강남   강북
year          
2000  3.3  NaN
2001  NaN  2.5
2002  3.0  2.0
'''
print(df['pop'].describe())
'''
count    4.000000
mean     2.700000
std      0.571548
min      2.000000
25%      2.375000
50%      2.750000
75%      3.075000
max      3.300000
'''

 

groupby

hap = df.groupby(['city'])
print(hap.sum()) # city별 합

print(df.groupby(['city']).sum()) # city별 합
'''
      year  pop
city           
강남    4002  6.3
강북    4003  4.5
'''
print(df.groupby(['city', 'year']).sum()) # city, year 별 합
'''
           pop
city year     
강남   2000  3.3
     2002  3.0
강북   2001  2.5
     2002  2.0
'''
print(df.groupby(['city', 'year']).mean()) # city, year별 평균
'''
           pop
city year     
강남   2000  3.3
     2002  3.0
강북   2001  2.5
     2002  2.0
'''

 

pivot_table : pivot, groupby의 중간 성격

print(df)
'''
  city  year  pop
0   강남  2000  3.3
1   강북  2001  2.5
2   강남  2002  3.0
3   강북  2002  2.0
'''

print(df.pivot_table(index=['city']))
print(df.pivot_table(index=['city'], aggfunc=np.mean)) # default : aggfunc=np.mean 
'''
       pop    year
city              
강남    3.15  2001.0
강북    2.25  2001.5
'''

print(df.pivot_table(index=['city', 'year'], aggfunc=[len, np.sum]))
'''
           len  sum
           pop  pop
city year          
강남   2000  1.0  3.3
     2002  1.0  3.0
강북   2001  1.0  2.5
     2002  1.0  2.0
'''

print(df.pivot_table(values=['pop'], index = 'city')) # city별 합의 평균
print(df.pivot_table(values=['pop'], index = 'city', aggfunc=np.mean))
'''
       pop
city      
강남    3.15
강북    2.25
'''

print(df.pivot_table(values=['pop'], index = 'city', aggfunc=len))
'''
      pop
city     
강남    2.0
강북    2.0
'''

print(df.pivot_table(values=['pop'], index = ['year'], columns=['city']))
'''
      pop     
city   강남   강북
year          
2000  3.3  NaN
2001  NaN  2.5
2002  3.0  2.0
'''

print(df.pivot_table(values=['pop'], index = ['year'], columns=['city'], margins=True))
'''
       pop           
city    강남    강북  All
year                 
2000  3.30   NaN  3.3
2001   NaN  2.50  2.5
2002  3.00  2.00  2.5
All   3.15  2.25  2.7
'''

print(df.pivot_table(values=['pop'], index = ['year'], columns=['city'], margins=True, fill_value=0))
'''
       pop           
city    강남    강북  All
year                 
2000  3.30  0.00  3.3
2001  0.00  2.50  2.5
2002  3.00  2.00  2.5
All   3.15  2.25  2.7
'''

file i/o

 * pdex4_fileio.py

import pandas as pd

#local
df = pd.read_csv(r'../testdata/ex1.csv')
#web
df = pd.read_csv(r'https://raw.githubusercontent.com/pykwon/python/master/testdata_utf8/ex1.csv')

print(df, type(df))
'''
   bunho irum  kor  eng
0      1  홍길동   90   90
1      2  신기해   95   80
2      3  한국인  100   85
3      4  박치기   67   54
4      5  마당쇠   55  100 <class 'pandas.core.frame.DataFrame'>
'''

df = pd.read_csv(r'../testdata/ex2.csv', header=None)
print(df, type(df))
'''
   0   1   2   3      4
0  1   2   3   4  hello
1  5   6   7   8  world
2  9  10  11  12    foo <class 'pandas.core.frame.DataFrame'>
'''

df = pd.read_csv(r'../testdata/ex2.csv', names=['a', 'b', 'c', 'd', 'e'])
print(df, type(df))
'''
   a   b   c   d      e
0  1   2   3   4  hello
1  5   6   7   8  world
2  9  10  11  12    foo <class 'pandas.core.frame.DataFrame'>
'''

df = pd.read_csv(r'../testdata/ex2.csv', names=['a', 'b', 'c', 'd', 'e'], index_col = 'e')
print(df, type(df))
'''
       a   b   c   d
e                   
hello  1   2   3   4
world  5   6   7   8
foo    9  10  11  12 <class 'pandas.core.frame.DataFrame'>
'''

df = pd.read_csv(r'../testdata/ex3.txt')
print(df, type(df))
'''
               A         B         C
0  aaa -0.264438 -1.026059 -0.619500
1  bbb  0.927272  0.302904 -0.032399
2  ccc -0.264273 -0.386314 -0.217601
3  ddd -0.871858 -0.348382  1.100491 <class 'pandas.core.frame.DataFrame'>
'''

df = pd.read_csv(r'../testdata/ex3.txt', sep = '\s+', skiprows=[1, 3])
print(df, type(df))
'''
            A         B         C
bbb  0.927272  0.302904 -0.032399
ddd -0.871858 -0.348382  1.100491 <class 'pandas.core.frame.DataFrame'>
'''

df = pd.read_fwf(r'../testdata/data_fwt.txt', encoding = 'utf8', widths=(10, 3, 5), names = ('date', 'name', 'price'))
print(df, type(df))
'''
         date name  price
0  2017-04-10  네이버  32000
1  2017-04-11  네이버  34000
2  2017-04-12  네이버  33000
3  2017-04-10  코리아  22000
4  2017-04-11  코리아  21000
5  2017-04-12  코리아  24000 <class 'pandas.core.frame.DataFrame'>
'''

print(df['date'])
'''
0    2017-04-10
1    2017-04-11
2    2017-04-12
3    2017-04-10
4    2017-04-11
5    2017-04-12
'''

 

chunksize : 파일이 너무 큰 경우에는 나눠서 읽기 옵션을 사용

test = pd.read_csv('../testdata/data_csv2.csv', header=None, chunksize = 3)
print(test)
'''
    0      1     2
0   1     사과  3500
1   2      배  5000
2   3    바나나  1000
3   4     수박  7000
4   5     참외  2000
5   6  에스프레소  5500
6   7  아메리카노  2000
7   8   카페라떼  4000
8   9   카푸치노  4000
9  10   카페모카  5000

<pandas.io.parsers.TextFileReader object at 0x00000240E6E521C0>
'''
for p in test:
    #print(p)
    print(p.sort_values(by=2, ascending=True))
    print()
'''
   0    1     2
2  3  바나나  1000
0  1   사과  3500
1  2    배  5000

   0      1     2
4  5     참외  2000
5  6  에스프레소  5500
3  4     수박  7000

   0      1     2
6  7  아메리카노  2000
7  8   카페라떼  4000
8  9   카푸치노  4000

    0     1     2
9  10  카페모카  5000
'''

 

파일로 저장

items = {'apple':{'count':10, 'price':1500},
         'orange':{'count':5, 'price':500}}
print(items)
df = pd.DataFrame(items)
print(df)
'''
count     10       5
price   1500     500
'''

 

csv

df.to_csv('result1.csv', sep=',')
df.to_csv('result2.csv', sep=',', index=False) # 색인 제외
df.to_csv('result3.csv', sep=',', index=False, header=False) # 색인, 칼럼명 제외

 

html

data = df.T
'''
        count  price
apple      10   1500
orange      5    500
'''
print(data)
data.to_html('result1.html')

 

excel로 저장

df2 = pd.DataFrame({'data':[1,2,3,4,5]})
wr = pd.ExcelWriter('good.xlsx', engine='xlsxwriter')
df2.to_excel(wr, sheet_name = 'Sheet1')
wr.save()

 

excel로 읽기

exf = pd.ExcelFile('good.xlsx')
print(exf.sheet_names)

dfdf = exf.parse('Sheet1')
print(dfdf)
dfdf2 = pd.read_excel(open('good.xlsx','rb'), sheet_name='Sheet1')
print(dfdf2)
'''
['Sheet1']
   Unnamed: 0  data
0           0     1
1           1     2
2           2     3
3           3     4
4           4     5
'''

ElementTree : XML, HTML 문서 읽기

 * pdex5_etree.py

import xml.etree.ElementTree as etree

# 일반적인 형태의 파일읽기
xml_f = open("pdex5.xml","r", encoding="utf-8").read()
print(xml_f,"\n",type(xml_f))  # <class str> 이므로 str관련 명령만 사용 가능
print()

root = etree.fromstring(xml_f)
print(root,'\n', type(root))   # <class xml.etree.ElementTree.Element> Element 관련 명령 사용가능
print(root.tag, len(root.tag)) # items 5

 

xmlfile = etree.parse("pdex5.xml")
print(xmlfile)
root = xmlfile.getroot()
print(root.tag)                   # items
print(root[0].tag)                # item
print(root[0][0].tag)             # name
print(root[0][0].attrib)          # {'id': 'ks1'}
print(root[0][2].attrib.keys())   # dict_keys(['kor', 'eng'])
print(root[0][2].attrib.values()) # dict_values(['90', '80'])

 

 * pdex5.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- xml문서 최상위 해당 라인이 추가되어야 한다. -->
<items>
	<item>
		<name id="ks1">홍길동</name>
		<tel>111-1111</tel>
		<exam kor="90" eng="80"/>
	</item>
	<item>
		<name id="ks2">신길동</name>
		<tel>111-2222</tel>
		<exam kor="100" eng="50"/>
	</item>
</items>

 


Beautifulsoup : XML, HTML문서의 일부 자료 추출

 * pdex6_beautifulsoup.py

# Beautifulsoup : XML, HTML문서의 일부 자료 추출
# 라이브러리 설치 beautifulsoup4, request, lxml
# find(), select()
 
import requests  
from bs4 import BeautifulSoup
def go():
    base_url = "http://www.naver.com/index.html"
    
    #storing all the information including headers in the variable source code
    source_code = requests.get(base_url)
    
    #sort source code and store only the plaintext
    plain_text = source_code.text            # 문자열
    #print(plain_text)
    
    #converting plain_text to Beautiful Soup object so the library can sort thru it
    convert_data = BeautifulSoup(plain_text, 'lxml') # lxml의 HTML 해석기 사용
    
    # 해석 라이브러리
    # BeautifulSoup(markup, "html.parser")
    # BeautifulSoup(markup, "lxml")
    # BeautifulSoup(markup, ["lxml", "xml"])
    # BeautifulSoup(markup, "xml")
    # BeautifulSoup(markup, html5lib)
    
    # find 함수
    # find()
    # find_next()
    # find_all()
    
    for link in convert_data.findAll('a'):   # a tag search 
        href = link.get('href')              # href 속성 get
        #href = base_url + link.get('href')  #Building a clickable url
        print(href)                          #displaying href
go()

 

Beautifulsoup의 find(), select()

 * pdex7_beautifulsoup.py

from bs4 import BeautifulSoup

html_page = """
<html><body>
<h1>제목태그</h1>
<p>웹문서 읽기</p>
<p>원하는 자료 선택</p>
</body></html>
"""
print(html_page, type(html_page)) # <class str>

soup = BeautifulSoup(html_page, 'html.parser') # BeautifulSoup 객체 생성
print(type(soup))  # bs4.BeautifulSoup BeautifulSoup이 제공하는 명령 사용 가능
print()

h1 = soup.html.body.h1
print('h1 :', h1.string)  # h1 : 제목태그
p1 = soup.html.body.p     # 최초의 p
print('p1 :', p1.string)  # p1 : 웹문서 읽기

p2 = p1.next_sibling      # </p>
p2 = p1.next_sibling.next_sibling
print('p2 :', p2.string)  # p2 : 원하는 자료 선택

 

 find() 사용

html_page2 = """
<html><body>
<h1 id='title'>제목태그</h1>
<p>웹문서 읽기</p>
<p id='my'>원하는 자료 선택</p>
</body></html>
"""

soup2 = BeautifulSoup(html_page2, 'html.parser')
print(soup2.p, ' ', soup2.p.string)    # 직접 최초 tag 선택가능
                                        # <p>웹문서 읽기</p>   웹문서 읽기

print(soup2.find('p').string)          # find('태그명')
                                        # 웹문서 읽기

print(soup2.find('p', id='my').string) # find('태그명', id='아이디명')
                                        # 원하는 자료 선택

print(soup2.find_all('p'))             # find_all('태그명') 
                                        # [<p>웹문서 읽기</p>, <p id="my">원하는 자료 선택</p>]

print(soup2.find(id='title').string)   # find(id='아이디명')
                                        # 제목태그

print(soup2.find(id='my').string)
                                        # 원하는 자료 선택

 

find_all(), findeAll() 사용

html_page3 = """
<html><body>
<h1 id='title'>제목태그</h1>
<p>웹문서 읽기</p>
<p id='my'>원하는 자료 선택</p>
<div>
    <a href="https://www.naver.com">naver</a><br/>
    <a href="https://www.daum.net">daum</a><br/>
</div>
</body></html>
"""

soup3 = BeautifulSoup(html_page3, 'html.parser')
print(soup3.find('a'))             # <a href="https://www.naver.com">naver</a>

print(soup3.find('a').string)
# naver

print(soup3.find(['a', 'i']))      # find(['태그명1', '태그명2']) 
                                    # <a href="https://www.naver.com">naver</a>

print(soup3.find_all(['a', 'p']))  # [<p>웹문서 읽기</p>, <p id="my">원하는 자료 선택</p>, <a href="https://www.naver.com">naver</a>, <a href="https://www.daum.net">daum</a>]
print(soup3.findAll(['a', 'p']))   # 위와 동일

print(soup3.find_all('a'))         # a태그만
                                    # [<a href="https://www.naver.com">naver</a>, <a href="https://www.daum.net">daum</a>]

print(soup3)
print(soup3.prettify()) # 들여쓰기
print()

links = soup3.find_all('a')        # [<a href="https://www.naver.com">naver</a>, <a href="https://www.daum.net">daum</a>]
print(links)
for i in links:
    href = i.attrs['href']
    text = i.string
    print(href, text)
# https://www.naver.com naver
# https://www.daum.net daum

 

find() 정규표현식 사용

import re
links2 = soup3.find_all(href=re.compile(r'^https://'))
print(links2)                 # [<a href="https://www.naver.com">naver</a>, <a href="https://www.daum.net">daum</a>]

for k in links2:
    print(k.attrs['href'])
# https://www.naver.com
# https://www.daum.net

 

select() 사용(css의 selector)

html_page4 = """
<html><body>
<div id='hello'>
    <a href="https://www.naver.com">naver</a><br/>
    <a href="https://www.daum.net">daum</a><br/>
    <ul class="world">
        <li>안녕</li>
        <li>반가워</li>
    </ul>
</div>
<div id='hi'>
    seconddiv
</div>
</body></html>
"""

soup4 = BeautifulSoup(html_page4, 'lxml')
aa = soup4.select_one('div#hello > a').string # select_one() : 하나만 선택
print("aa :", aa)            # aa : naver

bb = soup4.select("div#hello ul.world > li") # > : 직계, 공백 : 자손, select() : 복수 선택. 객체리턴.
print("bb :", bb) # bb : [<li>안녕</li>, <li>반가워</li>]

for i in bb:
    print("li :", i.string)
# li : 안녕
# li : 반가워

 


웹문서 읽기 - web scraping

 * pdex8.py

import urllib.request as req
from bs4 import BeautifulSoup

url = "https://ko.wikipedia.org/wiki/%EC%9D%B4%EC%88%9C%EC%8B%A0"
wiki = req.urlopen(url)
print(wiki) # <http.client.HTTPResponse object at 0x00000267F71B1550>

soup = BeautifulSoup(wiki, 'html.parser')
# Chrome - F12 - 태그 오른쪽 클릭  - Copy - Copy selector
print(soup.select_one("#mw-content-text > div.mw-parser-output > p"))

 

url = "https://news.daum.net/society#1"
daum = req.urlopen(url)
soup = BeautifulSoup(daum, 'html.parser')
print(soup.select_one("div#kakaoIndex > a").string) # 본문 바로가기
datas = soup.select("div#kakaoIndex > a")

for i in datas:
    href = i.attrs['href']
    text = i.string
    print("href :{}, text:{}".format(href, text))
    #print("href :%s, text:%s"%(href, text))
# href :#kakaoBody, text:본문 바로가기
# href :#kakaoGnb, text:메뉴 바로가기
print()

datas2 = soup.findAll('a')
#print(datas2)
for i in datas2[:2]:
    href = i.attrs['href']
    text = i.string
    print("href :{}, text:{}".format(href, text))
    
# href :#kakaoBody, text:본문 바로가기
# href :#kakaoGnb, text:메뉴 바로가기

날씨 정보 예보

 * pdex9_weather.py

#<![CDATA[ ]]>
import urllib.request
import urllib.parse
from bs4 import BeautifulSoup
import pandas as pd
url = "http://www.weather.go.kr/weather/forecast/mid-term-rss3.jsp"
data = urllib.request.urlopen(url).read()
#print(data.decode('utf-8'))
soup = BeautifulSoup(urllib.request.urlopen(url).read(), 'lxml')
#print(soup)
print()

title = soup.find('title').string
print(title) # 기상청 육상 중기예보
#wf = soup.find('wf')
wf = soup.select_one('item > description > header > wf')
print(wf)


city = soup.find_all('city')
#print(city)
cityDatas = []
for c in city:
    #print(c.string)
    cityDatas.append(c.string)

df = pd.DataFrame()
df['city'] = cityDatas
print(df.head(3))
'''
  city
0   서울
1   인천
2   수원
'''

#tmEfs = soup.select_one('location data tmef')
#tmEfs = soup.select_one('location > data > tmef')
tmEfs = soup.select_one('location > province + city + data > tmef') # + 아래 형제
print(tmEfs) # <tmef>2021-02-28 00:00</tmef>

tempMins = soup.select('location > province + city + data > tmn')
tempDatas = []
for t in tempMins:
    tempDatas.append(t.string)
    
df['temp_min'] = tempDatas
print(df.head(3), len(df))
'''
  city temp_min
0   서울        3
1   인천        3
2   수원        2 41
'''
df.columns = ['지역', '최저기온']
print(df.head(3))
'''
   지역 최저기온
0  서울    3
1  인천    3
2  수원    2
'''
print(df.describe())
print(df.info())

# 파일로 저장
df.to_csv('날씨정보.csv', index=False)
df2 = pd.read_csv('날씨정보.csv')

print(df2.head(2))
print(df2[0:2])

print(df2.tail(2))
print(df2[-2:len(df)])
'''
     지역  최저기온
39   제주    10
40  서귀포    10
'''

print(df.iloc[0])
'''
지역      서울
최저기온     3
'''
print(type(df.iloc[0])) # Series

print(df.iloc[0:2, :])
'''
   지역 최저기온
0  서울    3
1  인천    3
'''
print(type(df.iloc[0:2, :])) # DataFrame
print("---")
print(df.iloc[0:2, 0:2])
'''
   지역 최저기온
0  서울    3
1  인천    3
0    서울
1    인천
'''
print(df['지역'][0:2])
'''
0    서울
1    인천
'''
print(df['지역'][:2])
'''
0    서울
1    인천
'''
print("---")
print(df.loc[1:3])
'''
   지역 최저기온
1  인천    3
2  수원    2
3  파주   -2
'''
print(df.loc[[1, 3]])
'''
   지역 최저기온
1  인천    3
3  파주   -2
'''

print(df.loc[:, '지역'])
'''
0      서울
1      인천
2      수원
3      파주
'''
print('----------')
df = df.astype({'최저기온':'int'})
print(df.info())
print('----------')
print(df['최저기온'].mean()) # 2.1951219512195124
print(df['최저기온'].std()) # 3.034958914014504
print(df['최저기온'].describe())
#print(df['최저기온'] >= 5)
print(df.loc[df['최저기온'] >= 5])
'''
     지역  최저기온
17   여수     5
19   광양     5
27   부산     7
28   울산     5
32   통영     6
35   포항     6
39   제주    10
40  서귀포    10
'''
print('----------')
print(df.sort_values(['최저기온'], ascending=True))
'''
     지역  최저기온
31   거창    -3
6    춘천    -3
3    파주    -2
4    이천    -2
34   안동    -2
13   충주    -1
7    원주    -1
'''

 웹 문서를 다운받아 파일로 저장하기 - 스케줄러

 * pdex10_schedule.py

# 웹 문서를 다운받아 파일로 저장하기 - 스케줄러
from bs4 import BeautifulSoup
import urllib.request as req
import datetime

def working():
    url = "https://finance.naver.com/marketindex/"
    data = req.urlopen(url)
    soup = BeautifulSoup(data, 'html.parser')
    price = soup.select_one("div.head_info > span.value").string
    print("미국 USD :", price) # 미국 USD : 1,108.90
    
    t = datetime.datetime.now()
    print(t) # 2021-02-25 14:52:30.108522
    fname = './usd/' + t.strftime('%Y-%m-%d-%H-%M-%S') + ".txt"
    print(fname) # 2021-02-25-14-53-59.txt
    
    with open(fname, 'w') as f:
        f.write(price)
    
# 스케줄러
import schedule   # pip install schedule
import time
 
# 한번만 실행
working(); 
# 10초에 한번씩 실행
schedule.every(10).second.do(working)
# 10분에 한번씩 실행
schedule.every(10).minutes.do(working)
# 매 시간 실행
schedule.every().hour.do(working)
# 매일 10:30 에 실행
schedule.every().day.at("10:30").do(working)
# 매주 월요일 실행
schedule.every().monday.do(working)
# 매주 수요일 13:15 에 실행
schedule.every().wednesday.at("13:15").do(working)

while True:
    schedule.run_pending()
    time.sleep(1)

 


urllib.request, requests 모듈로 웹 자료 읽기

 * pdex11.py

 방법 1

from bs4 import BeautifulSoup

import urllib.request
url = "https://movie.naver.com/movie/sdb/rank/rmovie.nhn" # 네이버 영화 랭킹 정보
data = urllib.request.urlopen(url).read()
print(data)
soup = BeautifulSoup(data, 'lxml')
print(soup)
print(soup.select("div.tit3"))
print(soup.select("div[class=tit3]")) # 위와 동일

for tag in soup.select("div[class=tit3]"):
    print(tag.text.strip())
'''
미션 파서블
극장판 귀멸의 칼날: 무한열차편
소울
퍼펙트 케어
새해전야
몬스터 헌터
'''

 

 방법 2

import requests
data = requests.get(url);
print(data.status_code, data.encoding) # 정보 반환. 200 MS949
datas = data.text
print(datas)

datas = requests.get(url).text; # 명령을 연속적으로 주고 읽음
soup2 = BeautifulSoup(datas, "lxml")
print(soup2)

m_list = soup2.findAll("div", "tit3")          # findAll("태그명", "속성명")
m_list = soup2.findAll("div", {'class':'tit3'}) # findAll("태그명", {'속성':'속성명'}) 
print(m_list)
count = 1
for i in m_list:
    title = i.find('a')
    #print(title)
    print(str(count) + "위 : " + title.string)
    count += 1
'''
1위 : 미션 파서블
2위 : 극장판 귀멸의 칼날: 무한열차편
3위 : 소울
4위 : 퍼펙트 케어
5위 : 새해전야
6위 : 몬스터 헌터
7위 : 더블패티
'''

 

네이버 실시간 검색어

import requests
from bs4 import BeautifulSoup  # html 분석 라이브러리

# 유저 설정
url = 'https://datalab.naver.com/keyword/realtimeList.naver?where=main'
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36'}

res = requests.get(url, headers = headers)
soup = BeautifulSoup(res.content, 'html.parser')

# span.item_title 정보를 선택
data = soup.select('span.item_title')
i = 1

for item in data:
    print(str(i) + ')' + item.get_text())
    i += 1
'''
1)함소원 진화
2)함소원
3)오은영
4)기성용
'''

 * pdex12_search.py

구글 검색기능

import requests
from bs4 import BeautifulSoup
import webbrowser

def searchFunc(search_word):
    base_url = "https://www.google.com/search?q={0}"
    #sword = base_url.format("colab")
    sword = base_url.format(search_word)
    print(sword) # https://www.google.com/search?q=colab
    
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36'}
    #plain_text = requests.get(sword)
    plain_text = requests.get(sword, headers=headers)
    #print(plain_text.text)
    soup = BeautifulSoup(plain_text.text, 'lxml')
    #print(soup)
    link_data = soup.select('div.yuRUbf > a')
    #print(link_data)
    for link in link_data:
        #print(link.attrs['href'])
        #print(type(link),type(str(link)))
        print(str(link).find('https'),str(link).find('ping') - 2)
        urls = str(link)[str(link).find('https'):str(link).find('ping') -2]
        print(urls)
        webbrowser.open(urls)
        
search_word = "파이썬"
    
searchFunc(search_word)

 


XML

 * pdex13_xml.py

 

xmlObj.select('태그명')

# XML로 제공된 강남구 도서간 정보 읽기
import urllib.request as req
from bs4 import BeautifulSoup

url = "http://openapi.seoul.go.kr:8088/sample/xml/SeoulLibraryTime/1/5/"
plainText = req.urlopen(url).read().decode() # url의 text read
#print(plainText)

xmlObj = BeautifulSoup(plainText, 'lxml') # xml 해석기 사용
libData = xmlObj.select('row')            # row 태그의 데이터 정보 객체에 저장
#print(libData)

for data in libData:
    name = data.find('lbrry_name').text   # row태그내 lbrry_name 태그 정보 read
    addr = data.find('adres').text        # row태그내 adres 태그 정보 read
    print('도서관명\t:', name,'\n주소\t:',addr)

 


json

 * pdex14.json

{
	"직원":{
		"이름":"홍길동",
		"직급":"대리",
		"전화":"010-222-2222"
	},
	"웹사이트":{
		"카페명":"cafe.daum.net/flowlife",
		"userid":"hell"
	}
}

 

 

 * pdex14_json.py

 

json.loads('json 문자열')

import json

json_file = "./pdex14.json" # 파일경로
json_data = {}

def readData(filename):
    f = open(filename, 'r', encoding="utf-8") # 파일 열기
    lines = f.read()                          # 파일 읽기
    f.close()                                 # 파일 닫기
    #print(lines)
    return json.loads(lines)                  # decoding str -> dict                        
    
def main():
    global json_file                          # 전역 변수 사용
    json_data = readData(json_file)           # json파일의 내용을 dict타입으로 반환
    print(type(json_data))                    # dict
    
    d1 = json_data['직원']['이름']              # data의 key로 value read
    d2 = json_data['직원']['직급']
    d3 = json_data['직원']['전화']
    print("이름 : " + d1 +" 직급 : "+d2 + " 전화 : "+d3)
    # 이름 : 홍길동 직급 : 대리 전화 : 010-222-2222

if __name__ == "__main__":
    main()

 

 

 * pdex15_json.py

jsonData.get('태그명')

# JSON으로 제공된 강남구 도서간 정보 읽기
import urllib.request as req
import json

url = "http://openapi.seoul.go.kr:8088/sample/json/SeoulLibraryTime/1/5/ "
plainText = req.urlopen(url).read().decode() # url text read 및 decode
print(plainText)

jsonData = json.loads(plainText)
print(jsonData['SeoulLibraryTime']['row'][0]["LBRRY_NAME"]) # LH강남3단지작은도서관

# get 함수
libData = jsonData.get("SeoulLibraryTime").get("row")
print(libData)

name = libData[0].get('LBRRY_NAME') # LH강남3단지작은도서관
print(name)
print()

for msg in libData:
    name = msg.get('LBRRY_NAME')
    tel = msg.get('TEL_NO')
    addr = msg.get('ADRES')
    print('도서관명\t:', name,'\n주소\t:',addr,'\n전화\t:',tel)
'''
도서관명    : LH강남3단지작은도서관 
주소    : 서울특별시 강남구 자곡로3길 22 
전화    : 02-459-8700
도서관명    : 강남구립못골도서관 
주소    : 서울시 강남구 자곡로 116 
전화    : 02-459-5522
도서관명    : 강남역삼푸른솔도서관 
주소    : 서울특별시 강남구 테헤란로8길 36. 4층 
전화    : 02-2051-1178
도서관명    : 강남한신휴플러스8단지작은도서관 
주소    : 서울특별시 강남구 밤고개로27길 20(율현동, 강남한신휴플러스8단지) 
전화    : 
도서관명    : 강남한양수자인작은씨앗도서관 
주소    : 서울특별시 강남구 자곡로 260 
전화    : 
'''

selenium : 자동 웹 브라우저 제어

anaconda 접속
pip install selenium

https://sites.google.com/a/chromium.org/chromedriver/home 접속
Latest stable release: ChromeDriver 88.0.4324.96 접속
chromedriver_win32.zip download
dowload 파일 특정경로에 압축풀어 이동

anaconda 접속

python
from selenium import webdriver
browser = webdriver.Chrome('D:/1. 프로그래밍/0. 설치 Program/Python/chromedriver')
browser.implicitly_wait(5)
browser.get('https://daum.net')
browser.quit()
import time
from selenium import webdriver
browser = webdriver.Chrome('D:/1. 프로그래밍/0. 설치 Program/Python/chromedriver')
browser.get('http://www.google.com/xhtml');
time.sleep(5)
search_box = browser.find_element_by_name('q')
search_box.send_keys('파이썬')
search_box.submit()
time.sleep(5)
browser.quit()

 

 * pdex16_selenium.py

# 셀레니움으로 임의의 사이트 화면 캡처
from selenium import webdriver

try:
    url = "http://www.daum.net"
    browser = webdriver.Chrome('D:/1. 프로그래밍/0. 설치 Program/Python/chromedriver')
    browser.implicitly_wait(3)

    browser.get(url);
    browser.save_screenshot("daum_img.png")
    browser.quit()
    print('성공')

except Exception:
    print('에러')

형태소 분석

 * nlp01.py

# 말뭉치 : 자연어 연구를 목적으로 수집된 샘플 dataset
# 형태소(단어로써 의미를 가지는 최소 단위) 분석 (한글) - 어근, 접두사, 접미사, 품사 형태로 분리한 데이터로 분석작업

from konlpy.tag import Kkma

kkma = Kkma()
#print(kkma)
phrase = "영국 제약사 아스트라제네카의 백신 1차분 접종은 오전 9시부터 전국의 요양원 직원들과 약 5200만명의 환자들에게 투여되기 시작했다. 반가워요"
print(kkma.sentences(phrase))
print(kkma.nouns(phrase)) # 명사 출력
print()

from konlpy.tag import Okt
okt = Okt()
print(okt.pos(phrase))               # 단어 + 품사
print(okt.pos(phrase, stem=True))    # 
print(okt.nouns(phrase))             # 명사 출력
print(okt.morphs(phrase))            # 모든 품사 출력

 

단어 빈도수

 * nlp2_webscrap

# 위키백과 사이트에서 원하는 단어 검색 후 형태소 분석. 단어 출현 빈도 수 출력.

import urllib
from bs4 import BeautifulSoup
from konlpy.tag import Okt
from urllib import parse # 한글 인코딩용

okt = Okt()
#para = input('검색 단어 입력 : ')
para = "이순신"
para = parse.quote(para)    # 한글 인코딩
url = "https://ko.wikipedia.org/wiki/" + para
print(url) # https://ko.wikipedia.org/wiki/%EC%9D%B4%EC%88%9C%EC%8B%A0

page = urllib.request.urlopen(url)        # url 열기
#print(page)

soup = BeautifulSoup(page.read(), 'lxml') # url 읽어. xml 해석기 사용
#print(soup)

wordList = []               # 형태소 분석으로 명사만 추출해 기억

for item in soup.select("#mw-content-text > div > p"): # p태그의 데이터를 읽는다
    #print(item)
    if item.string != None: # 태그 내부가 비어있으면 저장 하지않는다.
        #print(item.string)
        ss = item.string
        wordList += okt.nouns(ss) # 명사만 추출

print("wordList :", wordList)
print("단어 수 :", len(wordList))
'''
wordList : ['당시', '조산', '만호', '이순신', ...]
단어 수 : 241
'''

# 단어의 발생횟수를 dict type 당시 : 2 조산:5
word_dict = {}

for i in wordList:
    if i in word_dict: # dict에 없으면 추가 있으면 count+1
        word_dict[i] += 1
    else:
        word_dict[i] = 1
print("word_dict :", word_dict)
'''
word_dict : {'당시': 3, '조산': 1, '만호': 1,  ...}
'''

setdata = set(wordList)
print(setdata)
print("단어 수(중복 제거 후) :", len(setdata)) # 단어 수(중복 제거 후) : 169
print()

# 판다스의 series type으로 처리
import pandas as pd
woList = pd.Series(wordList)
print(woList[:5])
print(woList.value_counts()[:5]) # 단어 별 횟수 총 갯수 top 5
'''
0     당시
1     조산
2     만호
3    이순신
4     북방
dtype: object
이순신    14
척       7
배       7
대한      5
그       4
dtype: int64

당시      3
조산      1
만호      1
이순신    14
북방      1
'''
print()

woDict = pd.Series(word_dict)
print(woDict[:5])
print(woDict.value_counts())
'''
1     133
2      23
3       7
7       2
4       2
14      1
5       1
'''
print()

# DataFrame으로 처리
df1 = pd.DataFrame(wordList, columns =['단어'])
print(df1.head(5))
print()
'''
    단어
0   당시
1   조산
2   만호
3  이순신
4   북방
'''

# 단어 / 빈도수
df2 = pd.DataFrame([word_dict.keys(), word_dict.values()])
df2 = df2.T
df2.columns = ['단어', '빈도수']
print(df2.head(3))
'''
   단어  빈도수
0  당시    3
1  조산    1
2  만호    1
'''
df2.to_csv("./이순신.csv", sep=',', index=False)
df3 = pd.read_csv("./이순신.csv")
print(df3.head(3))
'''
   단어  빈도수
0  당시    3
1  조산    1
2  만호    1
'''

 

one_hot encoding

 * nlp3.py

# Word를 수치화해서 vector에 담기
import numpy as np

# 단어 one_hot encoding
data_list = ['python', 'lan', 'program', 'computer', 'say']
print(data_list)

values = []
for x in range(len(data_list)):
    values.append(x)

print(values) # [0, 1, 2, 3, 4]

values_len = len(values) # 5

one_hot = np.eye(values_len)
print(one_hot) # one_hot encoding
'''
[[1. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0.]
 [0. 0. 1. 0. 0.]
 [0. 0. 0. 1. 0.]
 [0. 0. 0. 0. 1.]]
'''

 

word2vec

 : 단어를 벡터로 변경

anaconda 접속
pip install gensim
conda remove --force scipy
pip install scipy
from gensim.models import word2vec 

sentence = [['python', 'lan', 'program', 'computer', 'say']]
model =word2vec.Word2Vec(sentences = sentence, min_count=1, size = 50) # 50개의 크기
print(model.wv)
word_vectors = model.wv
print("word_vectors.vocab : ", word_vectors.vocab) # key, value로 구성된 vocab obj
print()

vocabs = word_vectors.vocab.keys()
print("vocabs : ", vocabs)
# vocabs :  dict_keys(['python', 'lan', 'program', 'computer', 'say'])

vocab_val = word_vectors.vocab.values()
print("vocab_val : ", vocab_val)
# vocab_val :  dict_values([<gensim.models.keyedvectors.Vocab object at 0x00000234EE66F610>, <gensim.models.keyedvectors.Vocab object at 0x00000234F6674130>, <gensim.models.keyedvectors.Vocab object at 0x00000234F6674190>, <gensim.models.keyedvectors.Vocab object at 0x00000234F6674220>, <gensim.models.keyedvectors.Vocab object at 0x00000234F6809F10>])
print()

word_vectors_list = [word_vectors[v] for v in vocabs]
print(word_vectors_list)
print()
'''
[array([ 1.3842779e-03,  7.4106529e-03,  2.4765935e-03, -8.9635467e-03,
        8.0429604e-03,  7.1699792e-03, -1.5191999e-03,  3.6448328e-04,
       -1.7622416e-03, -5.8619846e-03, -5.2785235e-03,  1.9480551e-03,
'''

similarity() : 코사인 유사도(Cosine Similarity) 수식에 의한 단어 사이의 거리를 출력

print(word_vectors.similarity(w1 = 'lan', w2 = 'program')) # 단어간 유사도 거리 : 0.20018259
print(word_vectors.similarity(w1 = 'lan', w2 = 'say'))     # 단어간 유사도 거리 : -0.10073644
print()
print(model.wv.most_similar(positive='lan'))
# [('program', 0.20018261671066284), ('computer', 0.158003032207489), ('python', 0.11154142022132874), ('say', -0.10073643922805786)]
# 1에 가까울 수록 유사도가 좋음

 


 * nlp4.py

# 웹 뉴스 정보를 읽어 형태소 분석 = > 단어별 유사도 출력
import pandas as pd
from konlpy.tag import Okt

okt = Okt()

with open('news.txt', mode='r', encoding='utf8') as f:
    #print(f.read())
    lines = f.read().split('\n') # 줄 나누기
    print(len(lines))
    
wordDic = {} # 단어 수 확인을 위한 dict type

for line in lines:
    datas = okt.pos(line) # 품사 태깅
    #print(datas) # [('(', 'Punctuation'), ('경남', 'Noun'), ('=', 'Punctuation'), ...

    for word in datas:
        if word[1] == 'Noun':  # 명사만 작업에 참여
            #print(word) # ('경남', 'Noun')
            #print(word[0] in wordDic)
            if not (word[0] in wordDic): # 없으면 0, 있으면 count + 1
                wordDic[word[0]] = 0 # {word[0] : count, ... } 
            wordDic[word[0]] += 1

print(wordDic)
# {'경남': 9, '뉴스': 4, '김다솜': 1, '기자': 1, '가덕도': 14, ...
# 단어 건수 별 내림차순 정렬
keys = sorted(wordDic.items(), key= lambda x : x[1], reverse=True) # count로 내림차순 정렬
print(keys)
# DataFrame에 담기 - 단어, 건수
wordList = []
countList = []

for word, count in keys[:20]: #상위 20개만 작업
    wordList.append(word)
    countList.append(count)

df = pd.DataFrame()
df['word'] = wordList
df['count'] = countList
print(df) 
'''
      word  count
0       공항     19
1      가덕도     14
2       경남      9
3      특별법      9
4   시민사회단체      8
5       도내      6
'''
# word2vec
result = []
with open('news.txt', mode='r', encoding='utf8') as fr:
    lines = fr.read().split('\n') # 줄 나누기
    for line in lines:
        datas = okt.pos(line, stem=True) # 품사 태깅. stem : 원형 어근 형태로 처리. 한가하고 -> 한가하다
        #print(datas) # [('(', 'Punctuation'), ('경남', 'Noun'), ('=', 'Punctuation'), ...
        temp = []
        for word in datas:
            if not word[1] in ['Punctuation', 'Suffix', 'Josa', 'Verb', 'Modifier', 'Number', 'Determiner', 'Foreign']:
                temp.append(word[0]) # 한 줄당 단어
        temp2 = (" ".join(temp)).strip() # 공백 제거 후 띄어쓰기를 채워 합친다.
        result.append(temp2)
        
print(result)

fileName = "news2.txt"
with open(fileName, mode="w", encoding='utf8') as fw:
    fw.write('\n'.join(result)) # 각 줄을 \n로 이어준 후 저장
    print('저장 완료')

 

 * news.txt

(경남=뉴스1) 김다솜 기자 = 가덕도신공항 특별법의 국회통과를 앞둔 26일 경남 도내 시민사회단체와 정당에서 반대 의견이 나오고 있다.
경남기후위기비상행동, 민주노총 경남본부 등 도내 시민사회단체는 이날 오전 경남도청 앞에서 기자회견을 열어 관련 부처에서도 반대 의견을 표명한 가덕도신공항 특별법이 기득권 양당의 담합 행위라고 반발했다.
정의당 경남도당도 같은 입장을 담은 성명을 발표했다.
이들은 관련 부처에서도 반대하는 사업을 받아들일 수 없다고 강조했다. 국토교통부의 가덕도신공항 의견보고서에서 위험성, 효율성 등 부정적인 측면이 지적된 만큼 신중하게 판단해야 한다는 것이다.
국토교통부는 지난 24일 안정성, 시공성, 운영성 등 7가지 점검 내용이 담긴 의견보고서를 제시했다. 보고서는 가덕도신공항 건설 시 안전사고 위험성이 크게 증가하고, 환경훼손도 뒤따른다고 지적하고 있다.
법무부도 가덕도신공항 특별법이 개별적·구체적 사건만 규율하고 있어서 적법 절차 및 평등원칙에 위배될 우려가 있다는 입장을 전했다.
이번 가덕도신공항 특별법에 포함된 예비타당성 조사 면제에 대한 반응도 좋지 않다. 기획재정부는 대규모 신규 사업에서 예산 낭비를 방지하려면 타당성을 검증할 필요가 있다는 의견을 전했다.
도내 시민사회단체는 “관계 부처까지도 수용이 곤란하다고 말하고 있다”며 “설계 없이 공사를 할 수 있게 한 유례를 찾을 수 없는 이 기상천외한 가덕도신공항 특별법은 위험하기 짝이 없다”고 비판했다.
가덕도신공항 특별법 처리를 앞두고 도내 시민사회단체와 민주노총 경남본부, 정의당 경남도당은 26일 법안 폐기를 촉구했다. 이들은 가덕도신공항 건설로 얻는 피해가 막대하다는 점을 거듭 강조했다. (경남 시민사회단체 제공) © 뉴스1
가덕도신공항 특별법 처리를 앞두고 도내 시민사회단체와 민주노총 경남본부, 정의당 경남도당은 26일 법안 폐기를 촉구했다. 이들은 가덕도신공항 건설로 얻는 피해가 막대하다는 점을 거듭 강조했다. (경남 시민사회단체 제공) © 뉴스1
당초 동남권 관문공항을 세우기 위한 목적에도 어긋난다는 지적도 나온다. 부산시가 발표한 가덕도신공항 건설안은 국제선만 개항하고, 국내선은 김해공항만 개항하도록 했는데 동남권 관문공항으로 보기에는 현실적이지 못하다는 설명이다.
국제선과 국내선, 군시설 등 동남권 관문공항의 기본 요소를 갖추려면 부산시에서 추산한 7조5000억 원보다 많은 28조7000억 원이 필요하다는 점도 짚었다. 이는 이명박 정부에 시행된 4대강 사업 예산보다도 많은 액수다.
도내 시민사회단체는 “정부와 여당이 적폐라 비난했던 이명박의 4대강 살리기 사업보다 더 나갔다”며 “동네 하천 정비도 이렇게 하지 않는다”고 일갈했다.
정의당 경남도당도 “모든 분야에서 부적격하다는 가덕도신공항 특별법을 밀어붙이는 건 집권 여당의 명백한 입법권 남용”이라며 “1년 임시 부산시장 자리를 위해 백년지대계인 공항건설을 선거지대계로 전락시킨 더불어민주당과 국민의힘을 규탄한다”고 전했다.
한편 가덕도신공항 특별법은 오늘 국회 본회의를 거쳐 통과될 전망이다. 이 법안은 예비타당성조사를 면제하고, 다른 법률에 우선 적용시키자는 내용 등을 담고 있다.
allcotton@news1.kr
Copyright ⓒ 뉴스1코리아 www.news1.kr 무단복제 및 전재 – 재배포금지

 

 * news2.txt

경남 뉴스 김다솜 기자 가덕도 공항 특별법 국회통과 경남 도내 시민사회단체 정당 반대 의견 있다
경남 기후 위기 비상 행동 민주 노총 경남 본부 등 도내 시민사회단체 날 오전 경남 도청 앞 기자회견 관련 부처 반대 의견 표명 가덕도 공항 특별법 기득권 당 담합 행위 반발
정의당 남도 같다 입장 성명 발표
이 관련 부처 반대 사업 수 없다 강조 국토교통부 가덕도 공항 의견 보고서 위험성 효율 등 부정 측면 지적 만큼 신중하다 판단 것
국토교통부 지난 안정 공성 운영 등 가지 점검 내용 의견 보고서 제시 보고서 가덕도 공항 건설 시 안전 사고 위험성 크게 증가 환경 훼손 지적 있다
법무부 가덕도 공항 특별법 개별 구체 사건 규율 있다 적법 절차 및 평등 원칙 위배 우려 있다 입장 전
이번 가덕도 공항 특별법 포함 예비 타당성 조사 면제 대한 반응 좋다 기획재정부 대규모 신규 사업 예산 낭비 방지 타당성 검증 필요 있다 의견 전
도내 시민사회단체 관계 부처 수용 곤란하다 말 있다 며 설계 없이 공사 수 있다 유례 수 없다 이 기상 외한 가덕도 공항 특별법 위험하다 짝 없다 고 비판
가덕도 공항 특별법 처리 도내 시민사회단체 민주 노총 경남 본부 정의당 남도 법안 폐기 촉구 이 가덕도 공항 건설 피해 막대 점 거듭 강조 경남 시민사회단체 제공 뉴스
가덕도 공항 특별법 처리 도내 시민사회단체 민주 노총 경남 본부 정의당 남도 법안 폐기 촉구 이 가덕도 공항 건설 피해 막대 점 거듭 강조 경남 시민사회단체 제공 뉴스
당초 동남권 관문 공항 위 목적 지적도 부산시 발표 가덕도 공항 건설 국제선 개항 국내선 김해 공항 개항 동남권 관문 공항 보기 현실 못 설명
국제선 국내선 군시설 등 동남권 관문 공항 기본 요소 부산시 추산 원보 많다 원 필요하다 점도 이명박 정부 시행 대강 사업 예산 많다 액수
도내 시민사회단체 정부 여당 적폐 비난 이명박 대강 사업 더 며 동네 하천 정비 이렇게 고 일
정의당 남도 모든 분야 부 적격하다 가덕도 공항 특별법 건 집권 여당 명백하다 입법권 남용 라며 임시 부산시 자리 위해 백년 지대 공항 건설 선거 지대 전락 민주당 국민 힘 규탄 고 전
한편 가덕도 공항 특별법 오늘 국회 본회의 통과 전망 이 법안 예비 타당성조사 면제 다른 법률 우선 적용 내용 등 있다
allcotton@news1.kr
Copyright 뉴스 코리아 www.news1.kr 무단 복제 및 재 재 배포 금지
# 모델 생성
model = word2vec.Word2Vec(genObj, size=100, window=10, min_count=2, sg=1) # window : 참조 주변 단어 수, min_count : 2보다 적은 값은 모델 구성에서 제외, sg=0 cbow, sg=1 skip-gram,
#Cbow 주변 단어로 중심단어 예측
#skip-gram : 중심 단어로 주변단어 추측
print(model)
model.init_sims(replace=True) # 모델 제작 중 생성된 필요없는 메모리 해제

# 학습 시킨 모델은 저장 후 재사용 가능
try:
    model.save('news.model')
except Exception as e:
    print('err', e)

model = word2vec.Word2Vec.load('news.model')
print(model.wv.most_similar(positive=['사업']))
print(model.wv.most_similar(positive=['사업'], topn=3))
print(model.wv.most_similar(positive=['사업', '남도'], topn=3))
# positive : 단어 사전에 해당단어가 있을 확률
# negative : 단어 사전에 해당단어가 없을 확률
result = model.wv.most_similar(positive=['사업', '남도'], negative=['건설'])
print(result)

클라우드 차트

 * nlp5.py

# 검색 결과를 형태소 분석하여 단어 빈도수를 구하고 이를 기초로 워드 클라우드 차트 출력
from bs4 import BeautifulSoup
import urllib.request
from urllib.parse import quote

#keyboard = input("검색어")
keyboard = "주식"
#print(quote(keyboard)) # encoding

# 동아일보 검색 기능
target_url ="https://www.donga.com/news/search?query=" + quote(keyboard)
print(target_url)
source_code = urllib.request.urlopen(target_url)
soup = BeautifulSoup(source_code, 'lxml', from_encoding='utf-8')

msg = ""
for title in soup.find_all("p", "tit"):
    title_link = title.select("a")
    #print(title_link)
    article_url = title_link[0]['href'] # [<a href="https://www.donga.com/news/Issue/031407" target="_blank">독감<span cl ... 
    #print(article_url) # https://bizn.donga.com/3/all/20210226/105634947/2 ..
    
    source_article = urllib.request.urlopen(article_url) # 실제 기사
    soup = BeautifulSoup(source_article, 'lxml', from_encoding='utf-8')
    cotents = soup.select('div.article_txt')
    #print(cotents)
    for temp in cotents:
        item = str(temp.find_all(text=True))
        #print(item)
        msg = msg + item

print(msg)

from urllib.parse import quote

quote(문자열) : encoding

 

from konlpy.tag import Okt
from collections import Counter

nlp = Okt()
nouns = nlp.nouns(msg)
result = []
for temp in nouns:
    if len(temp) > 1:
        result.append(temp)
print(result)
print(len(result))
count = Counter(result)
print(count)
tag = count.most_common(50) # 상위 50개만 작업에 참여

 

anaconda prompt 실행
pip install simplejson
pip install pytagcloud

 

import pytagcloud

taglist = pytagcloud.make_tags(tag, maxsize=100)
print(taglist)

pytagcloud.create_tag_image(taglist, "word.png", size=(1000, 600), fontname="korean", rectangular=False)

# 저장된 이미지 읽기
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
# %matplotlib inline # 주피터
img = mpimg.imread("word.png")
plt.imshow(img)
plt.show()

# 브라우저로 출력
import webbrowser
webbrowser.open("word.png")

 

C:\Windows\Fonts 폰트 복사
C:\anaconda3\Lib\site-packages\pytagcloud\fonts 붙여넣기
fonts.json

{
        "name": "korean",
        "ttf": "malgun.ttf",
        "web": "http://fonts.googleapis.com/css?family=Nobile"
},

numpy 모듈

: 데이터 분석 시 과학적 계산을 위한 핵심 라이브러리
: ndarray 지원. 다차원 배열 객체.

: 선형대수 계산
: 파이썬 데이터 분석 핵심.

함수명 기능
import numpy as np
np.sum(x)
np.mean(x) 평균
np.var(x) 분산
np.std(x) 표준편차(√분산)
np.array(x, dtype=) np.narray타입으로 변경. dtype : 내부 요소 타입 변경가능.
type(x) 타입 반환
x.dtype 데이터 타입 반환
x.shape 행 열 수 반환 (튜플)
x.ndim 차원 수 반환
x.size 원소 수 반환
np.zeros((행 수, 열 수)) 0으로 채워진 (행 X 열)의 배열 생성
np.ones((행 수, 열 수)) 1으로 채워진 (행 X 열)의 배열 생성
np.full((행 수, 열 수), x) x로 채워진 (행 X 열)의 배열 생성
np.eye(x) x행 x열의 단위 행열 생성. (대각선으로 1 채워진 행열)
 np.random.rand(x) x개의 균등분포 난수 생성.
 np.random.randn(x) x개의 정규분포 난수 생성.(평균 : 0, 표준편차 : 1)
 np.random.randint(x, size(차원, 행, 열) 0 ~ x-1까지 난수를 가진 행 X 열 X 차원의 배열 생성
x.copy() 배열을 복사. (복사된 배열 수정 시 원본배열 변경사항 없음)
np.arange(x, y) x에서 y-1까지 array 생성.
x.reshape(행, 열) 배열을 행 수 X 열 수로 변경.
x.astype(y) x를 y타입으로 변경
np.add(x, y) 배열 x, y 더하기
np.substract(x, y) 배열 x, y 빼기
np.multiply(x, y) 배열 x, y 곱하기
np.div(x, y) 배열 x, y 나누기
np.dot(x, y) x배열 y배열 내적
np.cumsum(x) 누적 합
np.cumprod(x) 누적 곱
 np.unique(x) 배열의 중복된 값 제거
 np.instersect1d(x, y, assume_unique=True) x와 y의 교집합 (assume_unique=True : 중복허용)
 np.union1d(x, y) x와 y의 합집합
x.transpose()
행렬 위치 변경(전치)
x.T 전치
x.swapaxes(a, b) a차원과 b차원 위치 변경(전치)
np.c_[x, y] x 배열에 y 열 추가
np.r_[x, y] x 배열에 y 행 추가
np.append(x, y) x 배열에 y 열 추가
np.insert(x, a, y) x 배열에 a번째에 y 열에  추가
np.insert(x, a, y, axis=1) x 배열에 a번째에 y 행에  추가
np.delete(x, a) x배열에서 a 열 삭제
np.delete(x, a, axis=1) x배열에서 a 행 삭제
np.where(조건배열, x, y) 각 배열 index마다 조건이 True면 x값 출력, False면 y값 출력
np.concatenate([x, y])  x, y배열 결합
y1, y2, ... = np.split(x, n) x배열을 n개로 나눠 n개의 배열 리턴
y1, y2, ... = np.hsplit(x, n) x배열을 열로 나눠 n개의 배열 리턴
y1, y2, ... = np.vsplit(x, n) x배열을 행으로 나눠 n개의 배열 리턴
import random
random.randint(n) 0에서 n-1까지의 난수 1개 복원 추출
random.randint(start, end) start에서 end-1까지 난수 1개의 복원 추출
random.rand(n) 0에서 1 사이의 표준정규분포를 따르는 n개의 난수 추출.
random.rand(m, n) 0에서 1 사이의 표준정규분포를 따르는 m x n의 난수 추출.
random.randn(n) 평균 0, 표준편차 1인 가우시안 정규분포의 n개 난수 추출.
random.randn(m, n) 평균 0, 표준편차 1인 가우시안 정규분포의 m x n개 난수 추출.
random.sample(리스트, k=n) 리스트에서 n개의 난수 비복원 추출
np.random.choice(배열, n) 배열에서 n개의 복원 추출
np.random.choice(배열, n, replace=False) 배열에서 n개의 비복원 추출
np.random.choice(배열, n, replace=False, p=[0.1, 0.9]) 배열에서 n개의 비복원 추출. p는 n개의 원소를 가지고 총합이 1이어야함. p의 값에 따른 가중치 부여

 * numpy1

 - 기본 통계 함수를 직접 작성 후 함수와 결과 비교

grades = [1, 3, -2, 4]

print(grades)

def show_grades(grades):
  for g in grades:
    print(g, end = ' ')

show_grades(grades)
[1, 3, -2, 4]
1 3 -2 4 
grades = [1, 3, -2, 4]
def grades_sum(grades): # 합
  tot = 0
  for g in grades:
    tot += 9
  return tot

def grades_ave(grades): # 평균
  tot = greads_sum(grades)
  ave = tot / len(grades)
  return ave

def greades_variance(grades): # 분산
  ave = grades_ave(grades)
  vari = 0
  for su in grades:
    vari += (su - ave) ** 2
  return vari / len(grades)
  #return vari / (len(grades) - 1)

def grades_std(grades):  # 표준편차
    return greades_variance(grades) ** 0.5

print('합은 ', grades_sum(grades))
print('평균은 ', grades_ave(grades))
print('분산은 ', greades_variance(grades))
print('표준편차는 ', greades_variance(grades))

 

 - numpy 함수를 사용

import numpy as np
print('합은 ', np.sum(grades))
print('평균은 ', np.mean(grades))
print('분산은 ', np.var(grades))
print('표준편차는 ', np.std(grades))
합은  36
평균은  9.0
분산은  61.5
표준편차는  61.5

합은  6
평균은  1.5
분산은  5.25
표준편차는  2.29128784747792
함수명 기능
import numpy as np  
np.sum(x)
np.mean(x) 평균
np.var(x) 분산
np.std(x) 표준편차(√분산)

 

 * numpy2

import numpy as np

ss = ['tom', 'james', 'oscar']
print(ss, ' ', type(ss))
# ['tom', 'james', 'oscar']   <class 'list'>

ss2 = np.array(ss)
print(ss, ' ', type(ss2))
# ['tom', 'james', 'oscar']   <class 'numpy.ndarray'>
# 메모리 비교
li = list(range(1,10))
print(li)
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

print(li[0], li[1], ' ', id(li[0]), id(li[1]))
# 1 2   10914496 10914528

print(li * 10)
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print('-' * 10)
# ----------

# li 각 요소와 10 곱하기
for l in li:
    print(l * 10, end=' ')
# 10 20 30 40 50 60 70 80 90 
# ndarray
num_arr = np.array(li)
print(id(num_arr), id(num_arr[0]), id(num_arr[1]))
# 140361351910064 140361354499656 140361354499656

print(num_arr * 10)
# [10 20 30 40 50 60 70 80 90]

 => list의 각 요소는 각각 memory를 할당받아 메모리 소모가 크다.

      * 연산 시 전체 값을 반복한다.

 

 => array의 각 요소는 동일한 메모리를 할당 받아 메모리 소모가 작다.

      * 연산 시 각 요소에 연산된다.

 

# 배열의 속성은 모두 동일. 우선순위에 따라 data type이 변경됨.
a = np.array([1, 2, 3.2]) # 우선순위 int -> float -> complex -> str
a = np.array([1, 2, 3], dtype='float32') 

print(a, type(a), a.dtype, a.shape, a.ndim, a.size)
# [1. 2. 3.] <class 'numpy.ndarray'> float32 (3,) 1 3

print(a[0]) # 1.0

a[0] = 8
print(a[0]) # 8.0

b = np.array([[1,2,4], [4,5,6]])
print(b, b.shape)
'''
[[1 2 4]
 [4 5 6]] (2, 3)
'''

print(b[0,0]) # 1
print(b[0], b[[0]]) # 1차원, 2차원
# [1 2 4] [[1 2 4]]

 => 배열의 속성은 모두 동일. 우선순위에 따라 data type이 변경됨.

      우선순위 int -> float -> complex -> str

함수명 기능
np.array(x, dtype=) np.narray타입으로 변경. dtype : 내부 요소 타입 변경가능.
type(x) 타입 반환
x.dtype 데이터 타입 반환
x.shape 행 열 수 반환 (튜플)
x.ndim 차원 수 반환
x.size 원소 수 반환

 

c = np.zeros((2, 2)) # 2행 2열의 0으로 채워진 배열 생성
print(c)
[[0. 0.]
 [0. 0.]]

d = np.ones((2, 2)) # 2행 2열의 1으로 채워진 배열 생성
print(d)
[[1. 1.]
 [1. 1.]]

e = np.full((2, 2), 7) # 2행 2열의 7으로 채워진 배열 생성
print(e)
[[7 7]
 [7 7]]

f = np.eye(3) # 3행 3열의 단위행렬
print(f)
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]
함수명 기능
np.zeros((행 수, 열 수)) 0으로 채워진 (행 X 열)의 배열 생성
np.ones((행 수, 열 수)) 1으로 채워진 (행 X 열)의 배열 생성
np.full((행 수, 열 수), x) x로 채워진 (행 X 열)의 배열 생성
np.eye(x) x행 x열의 단위 행열 생성. (대각선으로 1 채워진 행열)

 

print(np.random.rand(5)) # 균등분포
[0.20323807 0.81989097 0.84142846 0.46991121 0.21930122]

print(np.mean(np.random.rand(5)))
0.4230689697221274

print(np.random.randn(5)) # 정규분포
[-1.52232689 -0.31403199 -0.81191411  1.16482644 -0.23161658]

print(np.mean(np.random.randn(5)))
0.6515764623112837

x1 = np.random.randint(10, size=6)
[8 3 5 4 3 7]

x2 = np.random.randint(10, size=(3,4))
[[8 9 0 6]
 [5 9 0 2]
 [0 4 7 0]]

x3 = np.random.randint(10, size=(3,4,4))
print(x1)
[[[8 1 9 1]
  [4 9 3 7]
  [8 8 4 0]
  [7 9 8 1]]

print(x2)
 [[0 9 1 5]
  [7 8 4 0]
  [4 6 4 2]
  [9 8 9 2]]

print(x3)
 [[3 5 9 5]
  [7 3 5 4]
  [1 0 5 7]
  [2 2 2 2]]]

print(x3.ndim, x3.shape)
3 (3, 4, 4)
함수명 기능
 np.random.rand(x) x개의 균등분포 난수 생성.
 np.random.randn(x) x개의 정규분포 난수 생성.(평균 : 0, 표준편차 : 1)
 np.random.randint(x, size(차원, 행, 열) 0 ~ x-1까지 난수를 가진 행 X 열 X 차원의 배열 생성

 

# 슬라이싱
a = np.array([1,2,3,4,5])
print(a, a[1], a[1:5:2], a[1:], a[1:5])
[1 2 3 4 5] 2 [2 4] [2 3 4 5] [2 3 4 5]

a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
print(a[:])
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

print(a[0], a[0][0], a[[0]])
[1 2 3 4] 1 [[1 2 3 4]]

print(a[1:])
[[ 5  6  7  8]
 [ 9 10 11 12]]

 => a[x:y:z] : index x에서 y-1까지 z간격의 슬라이싱

 => a    =    a[:]

 => a[x][y] : x행, y열의 값

 

print(a[1:, 0:2])
[[ 5  6]
 [ 9 10]]

print(a)
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

b = a[:2, 1:3] # 서브 배열
print(b)
[[2 3]
 [6 7]]

b[0,0] = 77
print(b)
[[77  3]
 [ 6  7]]

print(a)
[[ 1 77  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
aa = np.array([1,2,3])
print(aa)
[1 2 3]

bb = aa[1:3]
print(bb)
[2 3]

bb[0] = 100
print(aa)
[  1 100   3]

print(bb)
[100   3]

aa[1] = 50
print(aa)
[ 1 50  3]

print(bb)
[50  3]

 => a[x:y, b:c] : index x에서 y-1 각 행에서 index b에서 c-1까지의 열 데이터.

 => 서브배열을 수정하면 원본의 데이터도 수정된다.

 

cc = aa[1:3].copy() # 배열 복사본 작성
print(cc)
[50  3]

cc[0] = 99
print(cc)
[99  3]

print(aa)
[ 1 50  3]

 => copy()를 이용하여 복사 시 서브배열을 수정하여도 원본 데이터는 변경 되지않는다.

함수명 기능
x.copy() 배열을 복사. (복사된 배열 수정 시 원본배열 변경사항 없음)

 

 * numpy3

# 배열 연산
import numpy as np

x = np.array([[1,2],[3,4]], dtype=np.float64)
y = np.arange(5, 9).reshape((2,2)) # 배열 변경
y = y.astype(np.float32) # 타입 변경
print(x)
[[1. 2.]
 [3. 4.]]

print(y)
[[5. 6.]
 [7. 8.]]
함수명 기능
np.arange(x, y) x에서 y-1까지 array 생성.
x.reshape(행, 열) 배열을 행 수 X 열 수로 변경.
x.astype(y) x를 y타입으로 변경

 

print(x + y)
[[ 6.  8.]
 [10. 12.]]
 
print(np.add(x, y)) # numpy 유니버셜 함수
[[ 6.  8.]
 [10. 12.]]

print(x - y) # np.substract()
[[-4. -4.]
 [-4. -4.]]

print(x * y) # np.multiply()
[[ 5. 12.]
 [21. 32.]]

print(x / y) # np.divid()
[[0.2        0.33333333]
 [0.42857143 0.5       ]]
함수명 기능
np.add(x, y) 배열 x, y 더하기
np.substract(x, y) 배열 x, y 빼기
np.multiply(x, y) 배열 x, y 곱하기
np.div(x, y) 배열 x, y 나누기

 

# python 함수보다 numpy 지원 함수가 계산 속도가 빠름

big_arr = np.random.rand(1000000) # 난수 발생

%timeit sum(big_arr) # python 함수

# 10 loops, best of 3: 155 ms per loop
%timeit np.sum(big_arr) # numpy 함수
# The slowest run took 23.08 times longer than the fastest. This could mean that 
# an intermediate result is being cached. 1000 loops, best of 3: 538 µs per loop

 

# 내적
v = np.array([9, 10])
w = np.array([11, 12])
print(v * w)
[ 99 120]


print(v.dot(w))    # 219
print(np.dot(v,w)) # 219

print(x)
[[1. 2.]
 [3. 4.]]
 
print(np.dot(x, y))
[[19. 22.]
 [43. 50.]]
print(sum(x), np.sum(x))
[4. 6.] 10.0

print(np.cumsum(x)) # 누적 합
[ 1.  3.  6. 10.]

print(np.cumprod(x)) # 누적 곱
[ 1.  2.  6. 24.]

names = np.array(['tom', 'james', 'tom', 'oscar'])
names2 = np.array(['tom', 'page', 'john'])
print(np.unique(names)) # 중복 제거
['james' 'oscar' 'tom']

print(np.intersect1d(names, names2)) # 중복 제거
['tom']

print(np.intersect1d(names, names2, assume_unique=True)) # 중복 허용
['tom' 'tom']

print(np.union1d(names, names2))
['james' 'john' 'oscar' 'page' 'tom']
함수명 기능
np.dot(x, y) x배열 y배열 내적
np.cumsum(x) 누적 합
np.cumprod(x) 누적 곱
 np.unique(x) 배열의 중복된 값 제거
 np.instersect1d(x, y, assume_unique=True) x와 y의 교집합 (assume_unique=True : 중복허용)
 np.union1d(x, y) x와 y의 합집합

 

# 전치 : 행렬 위치 변경
print(x)
[[1. 2.]
 [3. 4.]]
 
print(x.T)
[[1. 3.]
 [2. 4.]]

print(x.transpose())
[[1. 3.]
 [2. 4.]]

print(x.swapaxes(0, 1))
[[1. 3.]
 [2. 4.]]
함수명 기능
x.transpose()
행렬 위치 변경(전치)
x.T 전치
x.swapaxes(a, b) a차원과 b차원 위치 변경(전치)

 

# Broadcasting : 크기가 다른 배열 간의 연산.
x = np.arange(1, 10).reshape(3, 3)
y = np.array([1, 0 , 1])
print(x)
[[1 2 3]
 [4 5 6]
 [7 8 9]]

print(y)
[1 0 1]

print(x + y)
[[ 2  2  4]
 [ 5  5  7]
 [ 8  8 10]]

 

# 배열에 행, 또는 열 추가
aa = np.eye(3)
print(aa)
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]

bb = np.c_[aa, aa[2]] # 2 열과 동일한 열 추가
print(bb)
[[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 1.]]

cc = np.r_[aa, [aa[2]]] # 2 행과 동일한 행 추가
print(cc)
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]
 [0. 0. 1.]]

a = np.array([1,2,3])
b = np.append(a, [4, 5]) # 열 방향 추가
print(b)
[1 2 3 4 5]

c = np.insert(a, 0, [6, 7]) # axis = 0, 열 방향 삽입
print(c)
[6 7 1 2 3]

d = np.delete(a, 1)
print(d)
[1 3]

# 2차원도 가능.. # axis = 0 열 방향,  axis = 1 행 방향
함수명 기능
np.c_[x, y] x 배열에 y 열 추가
np.r_[x, y] x 배열에 y 행 추가
np.append(x, y) x 배열에 y 열 추가
np.insert(x, a, y) x 배열에 a번째에 y 열에  추가
np.insert(x, a, y, axis=1) x 배열에 a번째에 y 행에  추가
np.delete(x, a) x배열에서 a 열 삭제
np.delete(x, a, axis=1) x배열에서 a 행 삭제

 

# where 조건 연산
x = np.array([1,2,3])
y = np.array([4,5,6])
conditionData = np.array([True, False, True])
print(np.where(conditionData, x, y))
[1 5 3]

aa = np.where(x >= 2)
print(aa) #(array([1, 2]),)

print(x[aa])
[2 3]

print(np.where(x >= 2, 'T', 'F'))
['F' 'T' 'T']

print(np.where(x >= 2, x, x + 200))
[201   2   3]
함수명 기능
np.where(조건배열, x, y) 각 배열 index마다 조건이 True면 x값 출력, False면 y값 출력

 

# 배열 결합
kbs = np.concatenate([x, y])
print(kbs)
[1 2 3 4 5 6]

x1, x2 = np.split(kbs, 2)
print(x1)
[1 2 3]

print(x2)
[4 5 6]

a = np.arange(1, 17).reshape((4, 4))
print(a)
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]
 [13 14 15 16]]

x1, x2 = np.hsplit(a, 2)
print(x1)
[[ 1  2]
 [ 5  6]
 [ 9 10]
 [13 14]]

print(x2)
[[ 3  4]
 [ 7  8]
 [11 12]
 [15 16]]

print(np.vsplit(a, 2))
[array([[1, 2, 3, 4],
       [5, 6, 7, 8]]), array([[ 9, 10, 11, 12],
       [13, 14, 15, 16]])]
함수명 기능
np.concatenate([x, y])  x, y배열 결합
y1, y2, ... = np.split(x, n) x배열을 n개로 나눠 n개의 배열 리턴
y1, y2, ... = np.hsplit(x, n) x배열을 열로 나눠 n개의 배열 리턴
y1, y2, ... = np.vsplit(x, n) x배열을 행으로 나눠 n개의 배열 리턴

 

 * numpy4

# 복원/ 비복원 추출 - 데이터 집합으로 부터 무작위로 일부 자료 선택
# 복원 - 추출된 데이터가 다시 추출가능한 추출.
import numpy as np
import random

li = np.array([1,2,3,4,5,6,7])
# 복원 추출
for _ in range(5): # 5개의 난수 추출(복원)
    print(li[random.randint(0, len(li) - 1)], end = ' ')
6 1 6 5 2 

# 비복원 추출
print(random.sample(list(li), k = 5)) # 5개의 난수 추출(비복원). list 타입만 가능. list 출력.
[3, 7, 2, 5, 6]

print(random.sample(range(1, 46), k = 6)) # 로또 번호 추출
[40, 29, 15, 24, 38, 7]
# choice
print(list(np.random.choice(range(1, 46), 6))) # 복원 추출. 1 ~ 46 까지 6개 추출.
[16, 24, 35, 34, 26, 35]

print(list(np.random.choice(range(1, 46), 6, replace=True))) # 복원 추출.
[1, 33, 13, 15, 42, 35]

print(list(np.random.choice(range(1, 46), 6, replace=False))) # 비복원 추출.
[39, 4, 1, 11, 27, 28]

# 가중치를 부여한 랜덤 추출
ar = 'air book cat desk, egg, fox, god'
ar = ar.split(' ') # ' '을 기준으로 분해.
print(ar)
['air', 'book', 'cat', 'desk,', 'egg,', 'fox,', 'god']

print(np.random.choice(ar, 3, p = [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.4]))
['god' 'desk,' 'god']
# p의 합은 1로 클 수록 추출될 확률이 증가한다.
함수명 기능
import random  
random.randint(n) 0에서 n-1까지의 난수 1개 복원 추출
random.randint(start, end) start에서 end-1까지 난수 1개의 복원 추출
random.rand(n) 0에서 1 사이의 표준정규분포를 따르는 n개의 난수 추출.
random.rand(m, n) 0에서 1 사이의 표준정규분포를 따르는 m x n의 난수 추출.
random.randn(n) 평균 0, 표준편차 1인 가우시안 정규분포의 n개 난수 추출.
random.randn(m, n) 평균 0, 표준편차 1인 가우시안 정규분포의 m x n개 난수 추출.
random.sample(리스트, k=n) 리스트에서 n개의 난수 비복원 추출
np.random.choice(배열, n) 배열에서 n개의 복원 추출
np.random.choice(배열, n, replace=False) 배열에서 n개의 비복원 추출
np.random.choice(배열, n, replace=False, p=[0.1, 0.9]) 배열에서 n개의 비복원 추출. p는 n개의 원소를 가지고 총합이 1이어야함. p의 값에 따른 가중치 부여

 

 

+ Recent posts

1