Python 병렬 처리를 위한 Dask
Python큰 데이터를 처리하기 위해서는 병렬처리가 효율적인데, 그래서 Apache Spark의 pyspark를 많이들 사용한다. 속도는 매우 빠르지만 Pandas에 익숙한 사람들은 불편한 점이 있다. 이를 해소시켜 줄만한 라이브러리가 바로 Dask이다. (그 외 modin, ray, vaex등이 있는듯 하니 관심있다면 찾아보자.) 병렬 컴퓨팅(Parallel Computing)이란? 여러 단계 별로 구성된 작업을 수행할 때 각 단계에서 이전 작업이 완료되기를 기다리지 않고 이들이 동시에 처리되도록 하는 것이다. 따라서 난이도는 각 작업의 특징에 따라 달라지는데, 각 작업의 시작과 끝을 제외하고 각 단계가 서로 독립적으로 수행되는 작업은 병렬화가 쉽고, 각 단계 사이의 많은 데이터가 전송되고 교환되어야 하는 작업은 병렬화가 어렵다. Dask 란? Dask는 Python 라이브러리로 기능면에서는 Apache Spark와 비슷하지만 numpy, pandas와 긴밀하게 연결되어 있어서 python 사용자들이 Spark보다 훨씬 쉽게 배우고 활용할 수 있고, 다임과 같은 두 가지 기능을 가진다. 1. 가상 데이터프레임 2. 병렬처리용 작업 스케줄러 가상 데이터프레임 가상 데이터프레임은 Pandas 데이터프레임과 비슷한 기능을 제공하지만 실제로 모든 데이터가 메모리 상에 로드되어 있는 것이 아니라 하나 이상의 파일 혹인 데이터베이스에 존재하는 채로 처리할 수 있는 기능이다. 따라서 메모리 크기와 관계 없이 엄청나게 큰 CSV 파일을 가상 데이터프레임으로 로드하거나 같은 형식의 데이터를 가진 여러개의 CSV 파일을 하나의 가상 데이터프레임에 로드할 수 있다. 실제로 Dask의 가상 데이터프레임을 어떻게 쓸 수 있는지 알아보기 위해 간단한 CSV 파일을 만들어 살펴보자. Writing data1.csv Dask 패키지가 설치 되어 있지 않다면 설치를 하고 해당 패키지를 임포트하자. Install conda install dask (anaconda environment) pip install "dask[complete]" (pip based installation) Dask DataFrame Structure: | | time | temperature | humidity | |----------------|-------|-------------|----------| | npartitions=1 | | | | | dtype | int64 | int64 | int64 | | ... | ... | ... | ... | Dask Name: , 1 tasks 사용법을 보면 기존에 Pandas 데이터프레임과 유사하지만 실제 결과를 보면 아직 데이터를 메모리에 읽지 않았기 때문에 값은 표시되지 않는다. 값을 실제로 표시하려면 , 명령을 내리면 해당 데이터를 읽어서 표시한다. | | time | temperature | humidity | |---|------|-------------|----------| | 0 | 0 | 22 | 58 | | 1 | 1 | 21 | 57 | | 2 | 2 | 25 | 57 | | 3 | 3 | 26 | 55 | | 4 | 4 | 22 | 53 | 위의 경우 temperature 열의 평균을 구하기 위해 명령 입력하였지만 결과가 나오지 않는다. 그 이유는 는 연산 반환값의 결과가 아닌 작업(task)이기 때문이다. 구체적으로 어떤 작업인지를 보려면 매서드를 사용하여 작업 그래프(graph)를 볼 수 있다. 작업 그래프란 이 계산을 하기 위해 실제로 CPU가 해야할 일들의 순서도라고 생각하면 된다. 이 작업의 값을 실제로 구하려면 결과로 받은 작업 객체의 매서드를 호출해야 한다. 23.166666666666668 이번에는 이 값을 화씨로 변환해 보자 0 71.6 1 69.8 2 77.0 3 78.8 4 71.6 5 73.4 Name: temperature, dtype: float64 이번에는 이 값으로 원래의 temperature 열을 갱신해보자. 이 때는 Pandas의 문법을 쓰지 못하고 다음과 같이 메서드를 사용해야 한다. 메서드를 사용할 때는 를 할 필요가 없다. | | time | temperature | humidity | |---|------|-------------|----------| | 0 | 0 | 71.6 | 58 | | 1 | 1 | 69.8 | 57 | | 2 | 2 | 77.0 | 57 | | 3 | 3 | 78.8 | 55 | | 4 | 4 | 71.6 | 53 | 자료형을 변환하거나 새로운 열을 추가하는 것도 가능하다. | | time | temperature | humidity | title | |---|------|-------------|----------|-----------------| | 0 | 0 | 71.6 | 58 | 71.6 degree | | 1 | 1 | 69.8 | 57 | 69.8 degree | | 2 | 2 | 77.0 | 57 | 77.0 degree | | 3 | 3 | 78.8 | 55 | 78.8 degree | | 4 | 4 | 71.6 | 53 | 71.6 degree | Apache Spark를 사용해본 사람이라면 Transformation과 Action의 개념과 유사하다는 것을 눈치 챘을것이다! 복수 데이터에 대한 가상 데이터프레임 Dask는 가상 데이터프레임으로 원천 데이터 파일을 하나가 아닌 복수로 설정할 수도 있다. 예를 들어 앞서 보았던 파일 이외에도 다음과 같이 , 파일이 있을 경우, 이 파일을 한 번에 하나의 데이터프레임으로 읽어들일 수도 있다. Writing data2.csv Writing data3.csv 복수 파일은 와일드카드(*) 기호를 이용하여 읽는다. time 18 temperature 18 humidity 18 dtype: int64 count 18.000000 mean 23.166667 std 1.823055 min 21.000000 25% 22.000000 50% 22.500000 75% 24.500000 max 26.000000 Name: temperature, dtype: float64 대량 데이터의 병렬 처리 자 이제 Dask로 대량의 데이터를 처리해보자. 샘플로 쓸 데이터는 미국 정부가 발표하는 공개 정보 중 하나로 시카고의 범죄 관련 데이터이다. https://catalog.data.gov/dataset/crimes-2001-to-present-398a4 다음 명령으로 이 데이터를 다운로드 받을 수 있다. CSV 파일의 크기가 1.3GB가 넘으므로 다운로드에 10분 이상 걸릴수 있다. (만약 윈도우라면 wget을 사용하기 위해 https://eternallybored.org/misc/wget/ 여기에서 wget 최신 버전을 받고 c:\windows\system32에 위치시키면 된다.) ...... .......... .......... .......... 291K 1218900K .......... .......... .......... .......... .......... 11.7M 1218950K .......... .......... .......... .......... .......... 9.51M 1219000K .......... .......... .......... .......... .......... 14.1M 1219050K .......... .......... .......... .......... .......... 12.5M 1219100K .......... .......... .......... .......... .......... 10.1M 1219150K .......... .......... .......... .......... .......... 292K 1219200K .......... .......... .......... .......... .......... 9.68M 1219250K .......... .......... .......... .......... .......... 11.6M 1219300K .......... .......... .......... .......... .......... 12.1M 1219350K .......... .......... .......... .......... .......... 11.0M 1219400K .......... .......... .......... .......... .......... 10.7M 1219450K .......... .......... .......... .......... .......... 293K 1219500K .......... .......... .......... .......... .......... 11.5M 1219550K .......... .......... .......... .......... .......... 11.2M 1219600K .......... .......... .......... .......... .......... 9.82M 1219650K .......... .......... .......... .......... .......... 11.7M 1219700K .......... .......... .......... .......... .......... 11.9M 1219750K .......... .......... .......... .......... .......... 238K 1219800K .......... .......... .......... .......... .......... 11.3M 1219850K .......... .......... .......... .......... .......... 11.7M 1219900K .......... .......... .......... .......... .......... 12.0M 1219950K .......... .......... .......... .......... .......... 11.7M 1220000K .......... .......... .......... .......... .......... 9.24M 1220050K .......... .......... .......... .......... .......... 293K 1220100K .......... .......... .......... .......... .......... 11.9M 1220150K .......... .......... .......... .......... .......... 12.2M 1220200K .......... .......... .......... .......... .......... 11.2M 1220250K .......... .......... .......... .......... .......... 11.3M 1220300K .......... .......... .......... .......... .......... 12.1M 1220350K .......... .......... .......... .......... .......... 292K 1220400K .......... .......... .......... .......... .......... 11.8M 1220450K .......... .......... .......... .......... .......... 11.6M 1220500K .......... .......... .......... .......... .......... 9.90M 1220550K .......... .......... .......... .......... .......... 8.73M 1220600K .......... .......... .......... .......... .......... 12.4M 1220650K .......... .......... .......... .......... .......... 3.45M 1220700K .......... .......... .......... .......... .......... 315K 1220750K .......... .......... .......... .......... .......... 12.7M 1220800K .......... .......... .......... .......... .......... 9.12M 1220850K .......... .......... .......... .......... .......... 9.26M 1220900K .......... .......... .......... .......... .......... 11.2M 1220950K .......... .......... .......... .......... .......... 12.1M 1221000K .......... .......... .......... .......... .......... 296K 1221050K .......... .......... .......... .......... .......... 13.0M 1221100K .......... .......... .......... .......... .......... 12.3M 1221150K .......... .......... .......... .......... .......... 10.1M 1221200K .......... .......... .......... .......... .......... 8.55M 1221250K .......... .......... .......... .......... .......... 11.6M 1221300K .......... .......... .......... .......... .......... 249K 1221350K .......... .......... .......... .......... .......... 12.1M 1221400K .......... .......... .......... .......... .......... 10.8M 1221450K .......... .......... .......... .......... .......... 10.7M 1221500K .......... .......... .......... .......... .......... 13.7M 1221550K .......... .......... .......... .......... .......... 11.8M 1221600K .......... .......... .......... .......... .......... 665K 1221650K .......... .......... .......... .......... .......... 502K 1221700K .......... .......... .......... .......... .......... 12.0M 1221750K .......... .......... .......... .......... .......... 9.97M 1221800K .......... .......... .......... .......... .......... 13.0M 1221850K .......... .......... .......... .......... .......... 11.0M 1221900K .......... .......... .......... .......... .......... 12.7M 1221950K .......... .......... .......... .......... .......... 293K 1222000K .......... .......... .......... .......... .......... 12.0M 1222050K .......... .......... .......... .......... .......... 11.6M 1222100K .......... .......... .......... .......... .......... 11.7M 1222150K .......... .......... .......... .......... .......... 12.0M 1222200K .......... .......... .......... .......... .......... 11.1M 1222250K .......... .......... .......... .......... .......... 1.50M 1222300K .......... .......... .......... .......... .......... 355K 1222350K .......... .......... .......... .......... .......... 10.3M 1222400K .......... .......... .......... .......... .......... 8.38M 1222450K .......... .......... .......... .......... .......... 11.3M 1222500K .......... .......... .......... .......... .......... 12.0M 1222550K .......... .......... .......... .......... .......... 10.6M 1222600K .......... .......... .......... .......... .......... 297K 1222650K .......... .......... .......... .......... .......... 14.1M 1222700K .......... .......... .......... .......... .......... 9.30M 1222750K .......... .......... .......... .......... .......... 11.5M 1222800K .......... .......... .......... .......... .......... 9.04M 1222850K .......... .......... .......... .......... .......... 11.0M 1222900K .......... .......... .......... .......... .......... 685K 1222950K .......... .......... .......... .......... .......... 376K 1223000K .......... .......... .......... .......... .......... 10.8M 1223050K .......... .......... .......... .......... .......... 11.9M 1223100K .......... .......... .......... .......... .......... 11.5M 1223150K .......... .......... .......... .......... .......... 12.4M 1223200K .......... .......... .......... .......... .......... 9.14M 1223250K .......... .......... .......... .......... .......... 296K 1223300K .......... .......... .......... .......... .......... 11.7M 1223350K .......... .......... .......... .......... .......... 12.1M 1223400K .......... .......... .......... .......... .......... 10.1M 1223450K .......... .......... .......... .......... .......... 13.1M 1223500K .......... .......... .......... .......... .......... 11.4M 1223550K .......... .......... .......... .......... .......... 12.3M 1223600K .......... .......... .......... .......... .......... 294K 1223650K .......... .......... .......... .......... .......... 12.2M 1223700K .......... .......... .......... .......... .......... 11.6M 1223750K .......... .......... .......... .......... .......... 11.6M 1223800K .......... .......... .......... .......... .......... 10.2M 1223850K .......... .......... .......... .......... .......... 12.9M 1223900K .......... .......... .......... .......... .......... 294K 1223950K .......... .......... .......... .......... .......... 16.0M 1224000K .......... .......... .......... .......... .......... 9.55M 1224050K .......... .......... .......... .......... .......... 11.6M 1224100K .......... .......... .......... .......... .......... 11.2M 1224150K .......... .......... .......... .......... .......... 11.9M 1224200K .......... .......... .......... .......... .......... 1.24M 1224250K .......... .......... .......... .......... .......... 372K 1224300K .......... .......... .......... .......... .......... 13.5M 1224350K .......... .......... .......... .......... .......... 12.1M 1224400K .......... .......... .......... .......... .......... 8.88M 1224450K .......... .......... .......... .......... .......... 11.2M 1224500K .......... .......... .......... .......... .......... 11.7M 1224550K .......... .......... .......... .......... .......... 244K 1224600K .......... .......... .......... .......... .......... 11.3M 1224650K .......... .......... .......... .......... .......... 10.3M 1224700K .......... .......... .......... .......... .......... 13.8M 1224750K .......... .......... .......... .......... .......... 12.3M 1224800K .......... .......... .......... .......... .......... 9.29M 1224850K .......... .......... .......... .......... .......... 11.6M 1224900K .......... .......... .......... .......... .......... 296K 1224950K .......... .......... .......... .......... .......... 7.57M 1225000K .......... .......... .......... .......... .......... 11.0M 1225050K .......... .......... .......... .......... .......... 14.8M 1225100K .......... .......... .......... .......... .......... 11.1M 1225150K .......... .......... .......... .......... .......... 12.4M 1225200K .......... .......... .......... .......... .......... 297K 1225250K .......... .......... .......... .......... .......... 11.7M 1225300K .......... .......... .......... .......... .......... 8.52M 1225350K .......... .......... .......... .......... .......... 11.6M 1225400K .......... .......... .......... .......... .......... 11.4M 1225450K .......... .......... .......... .......... .......... 8.07M 1225500K .......... .......... .......... .......... .......... 11.7M 1225550K .......... .......... .......... .......... .......... 301K 1225600K .......... .......... .......... .......... .......... 7.09M 1225650K .......... .......... .......... .......... .......... 14.4M 1225700K .......... .......... .......... .......... .......... 9.71M 1225750K .......... .......... .......... .......... .......... 9.20M 1225800K .......... .......... .......... .......... .......... 11.6M 1225850K .......... .......... .......... .......... .......... 302K 1225900K .......... .......... .......... .......... .......... 10.3M 1225950K .......... .......... .......... .......... .......... 9.68M 1226000K .......... .......... .......... .......... .......... 9.45M 1226050K .......... .......... .......... .......... .......... 11.7M 1226100K .......... .......... .......... .......... .......... 8.02M 1226150K .......... .......... .......... .......... .......... 11.8M 1226200K .......... .......... .......... .......... .......... 247K 1226250K .......... .......... .......... .......... .......... 12.0M 1226300K .......... .......... .......... .......... .......... 11.7M 1226350K .......... .......... .......... .......... .......... 11.3M 1226400K .......... .......... .......... .......... .......... 9.61M 1226450K .......... .......... .......... .......... .......... 12.1M 1226500K .......... .......... .......... .......... .......... 295K 1226550K .......... .......... .......... .......... .......... 13.4M 1226600K .......... .......... .......... .......... .......... 10.9M 1226650K .......... .......... .......... .......... .......... 12.1M 1226700K .......... .......... .......... .......... .......... 9.85M 1226750K .......... .......... .......... .......... .......... 14.1M 1226800K .......... .......... .......... .......... .......... 2.31M 1226850K .......... .......... .......... .......... .......... 327K 1226900K .......... .......... .......... .......... .......... 11.7M 1226950K .......... .......... .......... .......... .......... 11.4M 1227000K .......... .......... .......... .......... .......... 11.1M 1227050K .......... .......... .......... .......... .......... 9.91M 1227100K .......... .......... .......... .......... .......... 13.9M 1227150K .......... .......... .......... .......... .......... 296K 1227200K .......... .......... .......... .......... .......... 8.93M 1227250K .......... .......... .......... .......... .......... 12.0M 1227300K .......... .......... .......... .......... .......... 11.2M 1227350K .......... .......... .......... .......... .......... 12.1M 1227400K .......... .......... .......... .......... .......... 11.2M 1227450K .......... .......... .......... .......... .......... 9.48M 1227500K .......... .......... .......... .......... .......... 299K 1227550K .......... .......... .......... .......... .......... 10.4M 1227600K .......... .......... .......... .......... .......... 9.38M 1227650K .......... .......... .......... .......... .......... 12.0M 1227700K .......... .......... .......... .......... .......... 11.5M 1227750K .......... .......... .......... .......... .......... 9.85M 1227800K .......... .......... .......... .......... .......... 247K 1227850K .......... .......... .......... .......... .......... 13.2M 1227900K .......... .......... .......... .......... .......... 532K 1227950K .......... .......... .......... .......... .......... 15.7M 1228000K .......... .......... .......... .......... .......... 19.8M 1228050K .......... .......... .......... .......... .......... 23.8M 1228100K .......... .......... .......... .......... .......... 33.4M 1228150K .......... .......... .......... .......... .......... 571K 1228200K .......... .......... .......... .......... .......... 11.0M 1228250K .......... .......... .......... .......... .......... 10.5M 1228300K .......... .......... .......... .......... .......... 12.0M 1228350K .......... .......... .......... .......... .......... 11.1M 1228400K .......... .......... .......... .......... .......... 10.6M 1228450K .......... .......... .......... .......... .......... 1.27M 1228500K .......... .......... .......... .......... .......... 374K 1228550K .......... .......... .......... .......... .......... 11.0M 1228600K .......... .......... .......... .......... .......... 11.2M 1228650K .......... .......... .......... .......... .......... 12.3M 1228700K .......... .......... .......... .......... .......... 11.6M 1228750K .......... .......... .......... .......... .......... 11.6M 1228800K .......... .......... .......... .......... .......... 295K 1228850K .......... .......... .......... .......... .......... 11.6M 1228900K .......... .......... .......... .......... .......... 11.9M 1228950K .......... .......... .......... .......... .......... 9.56M 1229000K .......... .......... .......... .......... .......... 10.9M 1229050K .......... .......... .......... .......... .......... 14.5M 1229100K .......... .......... .......... .......... .......... 12.2M 1229150K .......... .......... .......... .......... .......... 296K 1229200K .......... .......... .......... .......... .......... 11.8M 1229250K .......... .......... .......... .......... .......... 11.2M 1229300K .......... .......... .......... .......... .......... 12.0M 1229350K .......... .......... .......... .......... .......... 10.5M 1229400K .......... .......... .......... .......... .......... 12.1M 1229450K .......... .......... .......... .......... .......... 11.9M 1229500K .......... .......... .......... .......... .......... 245K 1229550K .......... .......... .......... .......... .......... 10.8M 1229600K .......... .......... .......... .......... .......... 11.7M 1229650K .......... .......... .......... .......... .......... 11.6M 1229700K .......... .......... .......... .......... .......... 12.0M 1229750K .......... .......... .......... .......... .......... 11.0M 1229800K .......... .......... .......... .......... .......... 297K 1229850K .......... .......... .......... .......... .......... 13.2M 1229900K .......... .......... .......... .......... .......... 11.9M 1229950K .......... .......... .......... .......... .......... 8.50M 1230000K .......... .......... .......... .......... .......... 13.2M 1230050K .......... .......... .......... .......... .......... 11.5M 1230100K .......... .......... .......... .......... .......... 12.3M 1230150K .......... .......... .......... .......... .......... 296K 1230200K .......... .......... .......... .......... .......... 14.5M 1230250K .......... .......... .......... .......... .......... 11.9M 1230300K .......... .......... .......... .......... .......... 10.7M 1230350K .......... .......... .......... .......... .......... 10.3M 1230400K .......... .......... .......... .......... .......... 11.6M 1230450K .......... .......... .......... .......... .......... 11.4M 1230500K .......... .......... .......... .......... .......... 299K 1230550K .......... .......... .......... .......... .......... 11.4M 1230600K .......... .......... .......... .......... .......... 11.9M 1230650K .......... .......... .......... .......... .......... 8.88M 1230700K .......... .......... .......... .......... .......... 17.3M 1230750K .......... .......... .......... .......... .......... 9.29M 1230800K .......... .......... .......... .......... .......... 11.7M 1230850K .......... .......... .......... .......... .......... 298K 1230900K .......... .......... .......... .......... .......... 13.7M 1230950K .......... .......... .......... .......... .......... 8.85M 1231000K .......... .......... .......... .......... .......... 12.1M 1231050K .......... .......... .......... .......... .......... 15.8M 1231100K .......... .......... .......... .......... .......... 10.8M 1231150K .......... .......... .......... .......... .......... 9.94M 1231200K .......... .......... .......... .......... .......... 247K 1231250K .......... .......... .......... .......... .......... 11.8M 1231300K .......... .......... .......... .......... .......... 9.64M 1231350K .......... .......... .......... .......... .......... 13.5M 1231400K .......... .......... .......... .......... .......... 12.5M 1231450K .......... .......... .......... .......... .......... 11.5M 1231500K .......... .......... .......... .......... .......... 11.7M 1231550K .......... .......... .......... .......... .......... 139K 1231600K .......... .......... .......... .......... .......... 17.9M 1231650K .......... .......... .......... .......... .......... 28.4M 1231700K .......... .......... .......... .......... .......... 21.4M 1231750K .......... .......... .......... .......... .......... 21.0M 1231800K .......... .......... .......... .......... .......... 14.8M 1231850K .......... .......... .......... .......... .......... 22.9M 1231900K .......... .......... .......... .......... .......... 27.3M 1231950K .......... .......... .......... .......... .......... 26.0M 1232000K .......... .......... .......... .......... .......... 20.2M 1232050K .......... .......... .......... .......... .......... 21.5M 1232100K .......... .......... .......... .......... .......... 24.6M 1232150K .......... .......... .......... .......... .......... 297K 1232200K .......... .......... .......... .......... .......... 8.90M 1232250K .......... .......... .......... .......... .......... 7.73M 1232300K .......... .......... .......... .......... .......... 9.98M 1232350K .......... .......... .......... .......... .......... 6.42M 1232400K .......... .......... .......... .......... .......... 298K 1232450K .......... .......... .......... .......... .......... 9.66M 1232500K .......... .......... .......... .......... .......... 8.40M 1232550K .......... .......... .......... .......... .......... 7.90M 1232600K .......... .......... .......... .......... .......... 9.12M 1232650K .......... .......... .......... .......... .......... 7.96M 1232700K .......... .......... .......... .......... .......... 248K 1232750K .......... .......... .......... .......... .......... 9.37M 1232800K .......... .......... .......... .......... .......... 12.2M 1232850K .......... .......... .......... .......... .......... 11.7M 1232900K .......... .......... .......... .......... .......... 11.8M 1232950K .......... .......... .......... .......... .......... 668K 1233000K .......... .......... .......... .......... .......... 486K 1233050K .......... .......... .. 15.4M=13m22s 2020-11-10 11:06:21 (1.50 MB/s) - 'crime.csv' saved [1262665799] 파일을 다운로드 받은 후에는 가상 데이터프레임으로 읽어들인다. 구체적인 데이터를 아직 모르기 때문에 우선 문자열 자료형으로 읽어들인다. 또 옵션을 로 해서 오류가 나는 데이터는 생략하도록 한다. Dask DataFrame Structure | | ID | Case Number | Date | Block | IUCR | Primary Type | Description | Location Description | Arrest | Domestic | Beat | District | Ward | Community Area | FBI Code | X Coordinate | Y Coordinate | Year | Updated On | Latitude | Longitude | Location | |---------------|--------|-------------|--------|--------|--------|--------------|-------------|-----------------------|--------|----------|-------|----------|-------|----------------|----------|--------------|--------------|-------|------------|----------|-----------|----------| | npartitions=20| | | | | | | | | | | | | | | | | | | | | | | | | object | object | object | object | object | object | object | object | object | object | object| object | object| object | object | object | object | object| object | object | object | object | | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | Dask Name: read-csv, 20 tasks 데이터 샘플 | Index | ID | Case Number | Date | Block | IUCR | Primary Type | Description | Location Description | Arrest | Domestic | ... | Ward | Community Area | FBI Code | X Coordinate | Y Coordinate | Year | Updated On | Latitude | Longitude | Location | |---------|--------------------------|-------------|----------------------|------------------|-------|--------------|-----------------|-----------------------|--------|----------|-----|------|----------------|----------|--------------|--------------|------|------------|----------|-----------|----------| | 196819 | 7026076 | HR432572 | 07/15/2009 04:00:00 PM | 007XX E 79TH ST | 0620 | BURGLARY | UNLAWFUL ENTRY | APARTMENT | false | false | ... | 6 | 44 | 05 | 1182734 | 1852793 | 2009 | 02/28/ | NaN | NaN | NaN | | 196820 | "error" : true | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | | 196821 | "message" : "Internal error" | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | | 196822 | "status" : 500 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | | 196823 | | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 표 설명: 열 이름: ID, Case Number, Date, Block, IUCR, Primary Type, 등. 총 22개의 열 중 일부만 표시되었습니다. 데이터는 오류와 누락된 값이 포함되어 있습니다. 이제 이 데이터프레임으로 분석을 시작해보자. 데이터 크기가 큰 만큼 시간이 오래 걸리기 때문에 친절하게도 Dask는 작업 진행도를 알 수 있는 라는 것을 제공한다. 다음과 같이 를 만들고 등록한다. 일단 등록하면 작업의 진행도를 프로그레스바 형태로 알려준다. 우선 각 열의 데이터 개수를 세어보자. [########################################] | 100% Completed | 21.9s Wall time: 21.9 s ID 5366005 Case Number 5365999 Date 5366001 Block 5366001 IUCR 5366001 Primary Type 5366001 Description 5366001 Location Description 5359222 Arrest 5366001 Domestic 5366001 Beat 5366001 District 5365954 Ward 4751265 Community Area 4753051 FBI Code 5366001 X Coordinate 5285054 Y Coordinate 5285054 Year 5366001 Updated On 5366001 Latitude 5285053 Longitude 5285053 Location 5285053 dtype: int64 데이터양이 많은 경우 이렇게 데이터 수를 세는 것만으로도 20초가 넘게 걸렸다. Dask는 이러한 대량 데이터의 분석 작업을 돕기 위한 작업 스케줄러(task scheduler)라는 것을 제공한다. 작업 스케줄러는 하나의 작업을 여러개의 쓰레드, 프로세스, 노드 등이 나누어 분담하도록 한다. 현재 Dask에서 제공하는 스케줄러의 종류는 다음과 같다. dask.get : 단일 쓰레드 dask.threaded.get : 멀티 쓰레드 풀(pool) dask.mutiprocessing.get : 멀티 프로세스 풀 distributed.Client.get : 여러대의 컴퓨터에서 분산 처리 병렬처리를 위해서는 어떠한 병렬 처리 방식을 사용할지, 작업 프로세스의 갯수는 어떻게 할지 등은 명령에서 인수로 설정해야 한다. 다음 코드는 멀티프로세싱을 하고 2개의 CPU 코어를 동시에 사용하도록 설정한 예이다. (물론 이 코드가 실행되는 컴튜터가 실제로 2개 이상의 코어를 가지고 있어야 성능이 개선된다.) [########################################] | 100% Completed | 15.6s Wall time: 15.6 s ID 5366005 Case Number 5365999 Date 5366001 Block 5366001 IUCR 5366001 Primary Type 5366001 Description 5366001 Location Description 5359222 Arrest 5366001 Domestic 5366001 Beat 5366001 District 5365954 Ward 4751265 Community Area 4753051 FBI Code 5366001 X Coordinate 5285054 Y Coordinate 5285054 Year 5366001 Updated On 5366001 Latitude 5285053 Longitude 5285053 Location 5285053 dtype: int64 실행되는 컴퓨터의 사양에 따라 다르긴 하겠지만, 처리속도가 빨라진 것을 볼 수 있다. 좀더 자세히 알아 보고 싶다면, 공식 문서를 살펴보자. > DASK Document (https://docs.dask.org/) 출처 : 데이터사이언스 스쿨(http://datascienceschool.net)
2020년 11월 01일27분DataFrame 시계열 자료 다루기
PythonDatetimeIndex 인덱스 시계열 자료는 인덱스가 날짜 혹은 시간인 데이터를 말한다. Pandas에서 시계열 자료를 생성하려면 인덱스를 자료형으로 만들어야 한다. 는 특정한 순간에 기록된 타임스탬프(timestamp) 형식의 시계열 자료를 다루기 위한 인덱스이다. 타임스탬프 인덱스의 라벨값이 반드시 일정한 간격일 필요는 없다. 인덱스는 다음과 같은 보조 함수를 사용하여 생성한다. pd.to_datetime 함수 pd.date_range 함수 함수를 쓰면 날짜/시간을 나타내는 문자열을 자동으로 datetime 자료형으로 바꾼 후 자료형 인덱스를 생성한다. DatetimeIndex(['2018-01-01', '2018-01-04', '2018-01-05', '2018-01-06'], dtype='datetime64[ns]', freq=None) 이렇게 만들어진 인덱스를 사용하여 시리즈나 데이터프레임을 생성하면 된다. 2018-01-01 1.764052 2018-01-04 0.400157 2018-01-05 0.978738 2018-01-06 2.240893 dtype: float64 함수를 쓰면 모든 날짜/시간을 일일히 입력할 필요없이 시작일과 종료일 또는 시작일과 기간을 입력하면 범위 내의 인덱스를 생성해 준다. DatetimeIndex(['2018-04-01', '2018-04-02', '2018-04-03', '2018-04-04', '2018-04-05', '2018-04-06', '2018-04-07', '2018-04-08', '2018-04-09', '2018-04-10', '2018-04-11', '2018-04-12', '2018-04-13', '2018-04-14', '2018-04-15', '2018-04-16', '2018-04-17', '2018-04-18', '2018-04-19', '2018-04-20', '2018-04-21', '2018-04-22', '2018-04-23', '2018-04-24', '2018-04-25', '2018-04-26', '2018-04-27', '2018-04-28', '2018-04-29', '2018-04-30'], dtype='datetime64[ns]', freq='D') DatetimeIndex(['2018-04-01', '2018-04-02', '2018-04-03', '2018-04-04', '2018-04-05', '2018-04-06', '2018-04-07', '2018-04-08', '2018-04-09', '2018-04-10', '2018-04-11', '2018-04-12', '2018-04-13', '2018-04-14', '2018-04-15', '2018-04-16', '2018-04-17', '2018-04-18', '2018-04-19', '2018-04-20', '2018-04-21', '2018-04-22', '2018-04-23', '2018-04-24', '2018-04-25', '2018-04-26', '2018-04-27', '2018-04-28', '2018-04-29', '2018-04-30'], dtype='datetime64[ns]', freq='D') 인수로 특정한 날짜만 생성되도록 할 수도 있다. 많이 사용되는 인수값은 다음과 같다. s: 초 T: 분 H: 시간 D: 일(day) B: 주말이 아닌 평일 W: 주(일요일) W-MON: 주(월요일) M: 각 달(month)의 마지막 날 MS: 각 달의 첫날 BM: 주말이 아닌 평일 중에서 각 달의 마지막 날 BMS: 주말이 아닌 평일 중에서 각 달의 첫날 WOM-2THU: 각 달의 두번째 목요일 Q-JAN: 각 분기의 첫달의 마지막 날 Q-DEC: 각 분기의 마지막 달의 마지막 날 보다 자세한 내용은 다음 웹사이트를 참조하자. https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#dateoffset-objects DatetimeIndex(['2018-04-02', '2018-04-03', '2018-04-04', '2018-04-05', '2018-04-06', '2018-04-09', '2018-04-10', '2018-04-11', '2018-04-12', '2018-04-13', '2018-04-16', '2018-04-17', '2018-04-18', '2018-04-19', '2018-04-20', '2018-04-23', '2018-04-24', '2018-04-25', '2018-04-26', '2018-04-27', '2018-04-30'], dtype='datetime64[ns]', freq='B') DatetimeIndex(['2018-01-07', '2018-01-14', '2018-01-21', '2018-01-28', '2018-02-04', '2018-02-11', '2018-02-18', '2018-02-25', '2018-03-04', '2018-03-11', '2018-03-18', '2018-03-25', '2018-04-01', '2018-04-08', '2018-04-15', '2018-04-22', '2018-04-29', '2018-05-06', '2018-05-13', '2018-05-20', '2018-05-27', '2018-06-03', '2018-06-10', '2018-06-17', '2018-06-24', '2018-07-01', '2018-07-08', '2018-07-15', '2018-07-22', '2018-07-29', '2018-08-05', '2018-08-12', '2018-08-19', '2018-08-26', '2018-09-02', '2018-09-09', '2018-09-16', '2018-09-23', '2018-09-30', '2018-10-07', '2018-10-14', '2018-10-21', '2018-10-28', '2018-11-04', '2018-11-11', '2018-11-18', '2018-11-25', '2018-12-02', '2018-12-09', '2018-12-16', '2018-12-23', '2018-12-30'], dtype='datetime64[ns]', freq='W-SUN') DatetimeIndex(['2018-01-01', '2018-01-08', '2018-01-15', '2018-01-22', '2018-01-29', '2018-02-05', '2018-02-12', '2018-02-19', '2018-02-26', '2018-03-05', '2018-03-12', '2018-03-19', '2018-03-26', '2018-04-02', '2018-04-09', '2018-04-16', '2018-04-23', '2018-04-30', '2018-05-07', '2018-05-14', '2018-05-21', '2018-05-28', '2018-06-04', '2018-06-11', '2018-06-18', '2018-06-25', '2018-07-02', '2018-07-09', '2018-07-16', '2018-07-23', '2018-07-30', '2018-08-06', '2018-08-13', '2018-08-20', '2018-08-27', '2018-09-03', '2018-09-10', '2018-09-17', '2018-09-24', '2018-10-01', '2018-10-08', '2018-10-15', '2018-10-22', '2018-10-29', '2018-11-05', '2018-11-12', '2018-11-19', '2018-11-26', '2018-12-03', '2018-12-10', '2018-12-17', '2018-12-24', '2018-12-31'], dtype='datetime64[ns]', freq='W-MON') shift 연산 시계열 데이터의 인덱스는 시간이나 날짜를 나타내기 때문에 날짜 이동 등의 다양한 연산이 가능하다. 예를 들어 연산을 사용하면 인덱스는 그대로 두고 데이터만 이동할 수도 있다. 2018-01-31 1.764052 2018-02-28 0.400157 2018-03-31 0.978738 2018-04-30 2.240893 Freq: M, dtype: float64 2018-01-31 NaN 2018-02-28 1.764052 2018-03-31 0.400157 2018-04-30 0.978738 Freq: M, dtype: float64 2018-01-31 0.400157 2018-02-28 0.978738 2018-03-31 2.240893 2018-04-30 NaN Freq: M, dtype: float64 2018-02-28 1.764052 2018-03-31 0.400157 2018-04-30 0.978738 2018-05-31 2.240893 Freq: M, dtype: float64 2018-02-04 1.764052 2018-03-04 0.400157 2018-04-01 0.978738 2018-05-06 2.240893 dtype: float64 resample 연산 resample 연산을 쓰면 시간 간격을 재조정하는 리샘플링(resampling)이 가능하다. 이 때 시간 구간이 작아지면 데이터 양이 증가한다고 해서 업-샘플링(up-sampling)이라 하고 시간 구간이 커지면 데이터 양이 감소한다고 해서 다운-샘플링(down-sampling)이라 부른다. 2018-03-22 0.625231 2018-03-23 -1.602058 2018-03-24 -1.104383 2018-03-25 0.052165 2018-03-26 -0.739563 2018-03-27 1.543015 2018-03-28 -1.292857 2018-03-29 0.267051 2018-03-30 -0.039283 2018-03-31 -1.168093 2018-04-01 0.523277 2018-04-02 -0.171546 2018-04-03 0.771791 2018-04-04 0.823504 2018-04-05 2.163236 2018-04-06 1.336528 2018-04-07 -0.369182 2018-04-08 -0.239379 2018-04-09 1.099660 2018-04-10 0.655264 Freq: D, dtype: float64 다운-샘플링의 경우에는 원래의 데이터가 그룹으로 묶이기 때문에 그룹바이(groupby)때와 같이 그룹 연산을 해서 대표값을 구해야 한다. 2018-01-07 0.697206 2018-01-14 0.468797 2018-01-21 0.249052 2018-01-28 0.301938 2018-02-04 0.023198 2018-02-11 0.283486 2018-02-18 -0.096136 2018-02-25 -0.446708 2018-03-04 0.155312 2018-03-11 0.200799 2018-03-18 -0.376808 2018-03-25 -0.895860 2018-04-01 -0.129493 2018-04-08 0.616422 2018-04-15 0.877462 Freq: W-SUN, dtype: float64 2018-01-31 -1.173123 2018-02-28 0.676433 2018-03-31 0.087551 2018-04-30 0.523277 Freq: M, dtype: float64 날짜가 아닌 시/분 단위에서는 구간위 왼쪽 한계값(가장 빠른 값)은 포함하고 오른쪽 한계값(가장 늦은 값)은 포함하지 않는다. 즉, 가장 늦은 값은 다음 구간에 포함된다. 예를 들어 10분 간경으로 구간을 만들면 10의 배수가 되는 시각은 구간의 시작점이 된다. 2018-01-01 00:00:00 2.259309 2018-01-01 00:01:00 -0.042257 2018-01-01 00:02:00 -0.955945 2018-01-01 00:03:00 -0.345982 2018-01-01 00:04:00 -0.463596 2018-01-01 00:05:00 0.481481 2018-01-01 00:06:00 -1.540797 2018-01-01 00:07:00 0.063262 2018-01-01 00:08:00 0.156507 2018-01-01 00:09:00 0.232181 2018-01-01 00:10:00 -0.597316 2018-01-01 00:11:00 -0.237922 2018-01-01 00:12:00 -1.424061 2018-01-01 00:13:00 -0.493320 2018-01-01 00:14:00 -0.542861 2018-01-01 00:15:00 0.416050 2018-01-01 00:16:00 -1.156182 2018-01-01 00:17:00 0.781198 2018-01-01 00:18:00 1.494485 2018-01-01 00:19:00 -2.069985 Freq: T, dtype: float64 2018-01-01 00:00:00 -0.155837 2018-01-01 00:10:00 -3.829915 2018-01-01 00:20:00 -0.115280 2018-01-01 00:30:00 -3.234560 2018-01-01 00:40:00 -4.452304 2018-01-01 00:50:00 -0.906751 Freq: 10T, dtype: float64 왼쪽이 아니라 오른쪽 한계값을 구간에 포함하려면 인수를 사용한다. 이 때는 10의 배수가 되는 시각이 앞 구간에 포함된다. 2017-12-31 23:50:00 2.259309 2018-01-01 00:00:00 -3.012462 2018-01-01 00:10:00 -2.806340 2018-01-01 00:20:00 -1.354903 2018-01-01 00:30:00 -4.004135 2018-01-01 00:40:00 -3.180252 2018-01-01 00:50:00 -0.595865 Freq: 10T, dtype: float64 매서드는 구간의 시고저종(open, high, low, close)값을 구한다. | 시간 | open | high | low | close | |--------------------------|-----------|-----------|-----------|-----------| | 2018-01-01 00:00:00 | 2.259309 | 2.259309 | -0.955945 | -0.463596 | | 2018-01-01 00:05:00 | 0.481481 | 0.481481 | -1.540797 | 0.232181 | | 2018-01-01 00:10:00 | -0.597316 | -0.237922 | -1.424061 | -0.542861 | | 2018-01-01 00:15:00 | 0.416050 | 1.494485 | -2.069985 | -2.069985 | | 2018-01-01 00:20:00 | 0.426259 | 0.676908 | -0.637437 | -0.132881 | | 2018-01-01 00:25:00 | -0.297791 | 1.152332 | -1.676004 | 1.079619 | | 2018-01-01 00:30:00 | -0.813364 | 0.521065 | -1.466424 | 0.141953 | | 2018-01-01 00:35:00 | -0.319328 | 0.694749 | -1.383364 | -1.383364 | | 2018-01-01 00:40:00 | -1.582938 | 0.610379 | -1.582938 | -0.596314 | | 2018-01-01 00:45:00 | -0.052567 | 0.523891 | -1.936280 | 0.088422 | | 2018-01-01 00:50:00 | -0.310886 | 1.955912 | -2.772593 | 1.955912 | | 2018-01-01 00:55:00 | 0.390093 | 0.493742 | -0.652409 | -0.116104 | 업-샘플링의 경우에는 실제로 존재하지 않는 데이터를 만들어야 한다. 이 때는 앞에서 나온 데이터를 뒤에서 그대로 쓰는 forward filling 방식과 뒤에서 나올 데이터를 앞에서 미리 쓰는 backward filling 방식을 사용할 수 있다. 각각 , 매서드를 이용한다. 2018-01-01 00:00:00 2.259309 2018-01-01 00:00:30 2.259309 2018-01-01 00:01:00 -0.042257 2018-01-01 00:01:30 -0.042257 2018-01-01 00:02:00 -0.955945 2018-01-01 00:02:30 -0.955945 2018-01-01 00:03:00 -0.345982 2018-01-01 00:03:30 -0.345982 2018-01-01 00:04:00 -0.463596 2018-01-01 00:04:30 -0.463596 2018-01-01 00:05:00 0.481481 2018-01-01 00:05:30 0.481481 2018-01-01 00:06:00 -1.540797 2018-01-01 00:06:30 -1.540797 2018-01-01 00:07:00 0.063262 2018-01-01 00:07:30 0.063262 2018-01-01 00:08:00 0.156507 2018-01-01 00:08:30 0.156507 2018-01-01 00:09:00 0.232181 2018-01-01 00:09:30 0.232181 Freq: 30S, dtype: float64 dt 접근자 datetime 자료형 시리즈에는 dt접근자가 있어 datetime 자료형이 가진 몇가지 유용한 속성과 매서드를 사용할 수 있다. 0 2020-12-25 1 2020-12-26 2 2020-12-27 3 2020-12-28 4 2020-12-29 ... 95 2021-03-30 96 2021-03-31 97 2021-04-01 98 2021-04-02 99 2021-04-03 Length: 100, dtype: datetime64[ns] 예를 들어 , , , 등의 속성을 이용하면 년, 월, 일, 요일 정보를 빼낼 수 있다. 0 2020 1 2020 2 2020 3 2020 4 2020 ... 95 2021 96 2021 97 2021 98 2021 99 2021 Length: 100, dtype: int64 0 4 1 5 2 6 3 0 4 1 .. 95 1 96 2 97 3 98 4 99 5 Length: 100, dtype: int64 매서드를 이용하여 문자열을 만드는 것도 가능하다. 0 2020년 12월 25일 1 2020년 12월 26일 2 2020년 12월 27일 3 2020년 12월 28일 4 2020년 12월 29일 ... 95 2021년 03월 30일 96 2021년 03월 31일 97 2021년 04월 01일 98 2021년 04월 02일 99 2021년 04월 03일 Length: 100, dtype: object Quiz, 다음 명령으로 만들어진 데이터프레임에 대해 월별 value의 합계를 구하라. (힌트 : 매서드와 접근자를 사용)) 출처 : 데이터사이언스 스쿨(http://datascienceschool.net)
2020년 10월 31일11분DataFrame 피봇과 그룹
Python피봇테이블 피봇테이블(pivot table)이란 데이터 열 중에서 두개의 열을 각각 행 인덱스, 열 인덱스로 사용하여 데이터를 조회하여 펼쳐놓은 것을 말한다. Pandas는 피봇테이블을 만들기 위한 매서드를 제공한다. 첫번째 인수로는 행 인덱스로 사용할 열 이름, 두뻔째 인수로는 열 인덱스로 사용할 열 이름, 그리고 마지막으로 데이터로 사용할 열 이름을 넣는다. Pandas는 지정된 두 열을 각각 행 인덱스와 열 인덱스로 바꾼 후 행 인덱스 라벨 값이 첫번째 키의 값과 같고 열 인덱스의 라벨 값이 두번째 키의 값과 같은 데이터를 찾아서 해당 칸에 넣는다. 만약 주어진 데이터가 존재하지 않으면 해당 칸에 값을 넣는다. 다음 데이터는 각 도시의 연도별 인구를 나타낸 것이다. | | 도시 | 연도 | 인구 | 지역 | |---|--------|-------|-----------|--------| | 0 | 서울 | 2015 | 9904312 | 수도권 | | 1 | 서울 | 2010 | 9631482 | 수도권 | | 2 | 서울 | 2005 | 9762546 | 수도권 | | 3 | 부산 | 2015 | 3448737 | 경상권 | | 4 | 부산 | 2010 | 3393191 | 경상권 | | 5 | 부산 | 2005 | 3512547 | 경상권 | | 6 | 인천 | 2015 | 2890451 | 수도권 | | 7 | 인천 | 2010 | 263203 | 수도권 | 이 데이터를 도시 이름이 열 인덱스가 되고 연도가 행 인덱스가 되어 행과 열 인덱스만 보면 어떤 도시의 어떤 시점의 인구를 쉽게 알수 있도록 피봇테이블로 만들어 보자. 명령으로 사용하고 행 인덱스 인수로는 , 열 인덱스 인수로는 , 데이터 이름으로 를 입력하면 된다. | 도시 | 2005 | 2010 | 2015 | |--------|------------|------------|------------| | 부산 | 3512547.0 | 3393191.0 | 3448737.0 | | 서울 | 9762546.0 | 9631482.0 | 9904312.0 | | 인천 | NaN | 263203.0 | 2890451.0 | 이 피봇테이블의 값 3512547은 "도시"가 부산이고 "연도"가 2005년인 데이터를 "인구"열에서 찾은 값이다. 2005년 인천의 인구는 데이터에 없기 때문에 으로 표시된다. 피봇테이블은 다음과 같이 명령과 명령을 사용하서 만들 수도 있다. | 도시 | 2005 | 2010 | 2015 | |--------|------------|------------|------------| | 부산 | 3512547.0 | 3393191.0 | 3448737.0 | | 서울 | 9762546.0 | 9631482.0 | 9904312.0 | | 인천 | NaN | 263203.0 | 2890451.0 | 행 인덱스나 열 인덱스를 리스트로 주는 경우에는 다중 인덱스 피봇 테이블을 생성한다. | | 연도 | 2005 | 2010 | 2015 | | --- | --- | --- | --- | --- | | 지역 | 도시 | | | | | 경상권 | 부산 | 3512547.0 | 3393191.0 | 3448737.0 | | 수도권 | 서울 | 9762546.0 | 9631482.0 | 9904312.0 | | 인천 | NaN | 263203.0 | 2890451.0 | 행 인덱스와 열 인덱스는 데이터를 찾는 키(key)의 역할을 한다. 따라서 키 값으로 데이터가 단 하나만 찾아져야 한다. 만약 행 인덱스와 열 인덱스 조건을 만족하는 데이터가 2개 이상인 경우에는 에러가 발생한다. 예를 들어 위 데이터프레임에서 ("지역", "연도")를 키로 하면 ("수도권", "2015")에 해당하는 값이 두개 이상이므로 다음과 같이 에러가 발생한다. ValueError: Index contains duplicate entries, cannot reshape 그룹분석 만약 키가 지정하는 조건에 맞는 데이터가 하나 이상이라서 데이터 그룹을 이루는 경우에는 그룹의 특성을 보여주는 그룹분석(group analysis)을 해야 한다. 그룹분석은 피봇테이블과 달리 키에 의해서 결정되는 데이터가 여러개가 있을 경우 미리 지정한 연선을 통해 그 그룹 데이터의 대표값을 계산한다. Pandas에서는 매서드를 사용하여 다음처럼 그룹분석을 한다. > 1. 분석하고자 하는 시리즈나 데이터프레임에 매서드를 호출하여 그룹화를 한다. > 2. 그룹 객체에 대해 그룹연산을 수행한다. 그룹연산 매서드 결과, 즉 클래스 객체의 뒤에 붙일 수 있는 그룹연산 매서드는 다양하다. 다음은 자주 사용되는 그룹연산 매서드들이다. , : 그룹 데이터의 개수 , , , : 그룹 데이터의 평균, 중앙값, 최소, 최대 , , , , : 그룹 데이터의 합계, 곱, 표준편차, 분산, 사분위수 , : 그룹 데이터중 가장 첫번째 데이터와 가장 나중 데이터와 이 외에도 많이 사용되는 것으로는 다음과 같은 그룹 연산이 있다. , 만약 원하는 구릅연산이 없는 경우 함수를 만들고 이 함수를 에 전달한다. 또는 여러가지 그룹연산을 동시에 하고 싶은 경우 함수 이름 문자열의 리스트를 전달한다. 하나의 그룹 대표값이 아니라 여러개의 값을 데이터프레임으로 구한다. 처럼 하나의 대표값이 아닌 데이터프레임을 출력하지만 원하는 그룹연산이 없는 경우에 사용한다. 그룹에 대한 대표값을 만드는 것이 아니라 그룹별 계산을 통해 데이터 자체를 변형한다. 예를 들어 다음과 같은 데이터가 있을 때 key1의 값(A 또는 B)에 따른 data1의 평균은 어떻게 구할까? | | key1 | key2 | data1 | data2 | | --- | --- | --- | --- | --- | | 0 | A | one | 1 | 10 | | 1 | A | two | 2 | 20 | | 2 | B | one | 3 | 30 | | 3 | B | two | 4 | 40 | | 4 | A | one | 5 | 50 | 명령을 사용하여 그룹 A와 그룹 B로 구분한 그룹 데이터를 만든다. 이 클래스 객체에는 각 그룹 데이터의 인덱스를 저장한 groups 속성이 있다. A그룹과 B그룹 데이터의 합계를 구하기 위해 이라는 그룹연산을 한다. | | data1 | data2 | | --- | --- | --- | | key1 | | | | A | 8 | 80 | | B | 7 | 70 | 클래스 객체를 명시적으로 얻을 필요가 없다면 매서드와 그룹연산 메서드를 연속으로 호출한다. 다음 예제는 열 에 대해서만 그룹연산을 하는 코드 이다. key1 A 8 B 7 Name: data1, dtype: int64 데이터를 그룹으로 나눈 클래스 객체 또는 그룹분석한 결과에서 만 뽑아도 된다. key1 A 8 B 7 Name: data1, dtype: int64 key1 A 8 B 7 Name: data1, dtype: int64 이번에는 복합 키 (key1, key2) 값에 따른 data1의 합계를 구하자. 분석하고자 하는 키가 복수이면 리스트를 사용한다. key1 key2 A one 6 two 2 B one 3 two 4 Name: data1, dtype: int64 이 결과를 명령으로 피봇 테이블 행태로 만들수도 있다. | key2 | one | two | | --- | --- | --- | | key1 | | | | A | 6 | 2 | | B | 3 | 4 | 그룹분석 기능을 사용하면 위의 인구 데이터로부터 지역별 합계를 구할 수도 있다. | | 도시 | 연도 | 인구 | 지역 | | --- | --- | --- | --- | --- | | 0 | 서울 | 2015 | 9904312 | 수도권 | | 1 | 서울 | 2010 | 9631482 | 수도권 | | 2 | 서울 | 2005 | 9762546 | 수도권 | | 3 | 부산 | 2015 | 3448737 | 경상권 | | 4 | 부산 | 2010 | 3393191 | 경상권 | | 5 | 부산 | 2005 | 3512547 | 경상권 | | 6 | 인천 | 2015 | 2890451 | 수도권 | | 7 | 인천 | 2010 | 263203 | 수도권 | | 연도 | 2005 | 2010 | 2015 | | --- | --- | --- | --- | | 지역 | | | | | 경상권 | 3512547 | 3393191 | 3448737 | | 수도권 | 9762546 | 9894685 | 12794763 | 다음 데이터는 150 송이의 붓꽃(iris)에 대해 붓꽃 종(species)별로 꽃받침길이(sepallangth), 꽃받침폭(sepalwidth), 꽃잎길이(tetallength), 꽃잎폭(petalwidth)을 측정한 데이터이다. | | sepallength | sepalwidth | petallength | petalwidth | 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 | | 3 | 4.6 | 3.1 | 1.5 | 0.2 | setosa | | 4 | 5.0 | 3.6 | 1.4 | 0.2 | setosa | | ... | ... | ... | ... | ... | ... | | 145 | 6.7 | 3.0 | 5.2 | 2.3 | virginica | | 146 | 6.3 | 2.5 | 5.0 | 1.9 | virginica | | 147 | 6.5 | 3.0 | 5.2 | 2.0 | virginica | | 148 | 6.2 | 3.4 | 5.4 | 2.3 | virginica | | 149 | 5.9 | 3.0 | 5.1 | 1.8 | virginica | 각 붓꽃 종별로 가장 큰 값과 가장 작은 값의 비율을 구해보자. 이러한 계산을 하는 그룹연산 매서드는 없으므로 직접 함수로 만들고 매서드를 이용해야 한다. | | sepallength | sepalwidth | petallength | petalwidth | | --- | --- | --- | --- | --- | | species | | | | | | setosa | 1.348837 | 1.913043 | 1.900000 | 6.000000 | | versicolor | 1.428571 | 1.700000 | 1.700000 | 1.800000 | | virginica | 1.612245 | 1.727273 | 1.533333 | 1.785714 | 매서드를 사용하면 다양한 기술 통계(descriptive statistics)값을 한 번에 구한다. 그룹별로 하나의 스칼라 값이 아니라 하나의 데이터프레임이 생성된다는 점에 주의하자. | | species | setosa | versicolor | virginica | | --- | --- | --- | --- | --- | | sepal_length | count | 50.000000 | 50.000000 | 50.000000 | | mean | 5.006000 | 5.936000 | 6.588000 | | std | 0.352490 | 0.516171 | 0.635880 | | min | 4.300000 | 4.900000 | 4.900000 | | 25% | 4.800000 | 5.600000 | 6.225000 | | 50% | 5.000000 | 5.900000 | 6.500000 | | 75% | 5.200000 | 6.300000 | 6.900000 | | max | 5.800000 | 7.000000 | 7.900000 | | sepal_width | count | 50.000000 | 50.000000 | 50.000000 | | mean | 3.428000 | 2.770000 | 2.974000 | | std | 0.379064 | 0.313798 | 0.322497 | | min | 2.300000 | 2.000000 | 2.200000 | | 25% | 3.200000 | 2.525000 | 2.800000 | | 50% | 3.400000 | 2.800000 | 3.000000 | | 75% | 3.675000 | 3.000000 | 3.175000 | | max | 4.400000 | 3.400000 | 3.800000 | | petal_length | count | 50.000000 | 50.000000 | 50.000000 | | mean | 1.462000 | 4.260000 | 5.552000 | | std | 0.173664 | 0.469911 | 0.551895 | | min | 1.000000 | 3.000000 | 4.500000 | | 25% | 1.400000 | 4.000000 | 5.100000 | | 50% | 1.500000 | 4.350000 | 5.550000 | | 75% | 1.575000 | 4.600000 | 5.875000 | | max | 1.900000 | 5.100000 | 6.900000 | | petal_width | count | 50.000000 | 50.000000 | 50.000000 | | mean | 0.246000 | 1.326000 | 2.026000 | | std | 0.105386 | 0.197753 | 0.274650 | | min | 0.100000 | 1.000000 | 1.400000 | | 25% | 0.200000 | 1.200000 | 1.800000 | | 50% | 0.200000 | 1.300000 | 2.000000 | | 75% | 0.300000 | 1.500000 | 2.300000 | | max | 0.600000 | 1.800000 | 2.500000 | 매서드를 사용하면 매서드처럼 하나의 그룹에 대해 하나의 대표값(스칼라 값)을 구하는게 아니라 데이터프레임을 만들 수 있다. 예를 들어 다음처럼 각 붓꽃 종별로 가장 꽃잎길이(petal length)가 큰 3개의 데이터를 뽑아낼 수도 있다. | | | sepallength | sepalwidth | petallength | petalwidth | species | | --- | --- | --- | --- | --- | --- | --- | | species | | | | | | | | setosa | 24 | 4.8 | 3.4 | 1.9 | 0.2 | setosa | | 44 | 5.1 | 3.8 | 1.9 | 0.4 | setosa | | 23 | 5.1 | 3.3 | 1.7 | 0.5 | setosa | | versicolor | 83 | 6.0 | 2.7 | 5.1 | 1.6 | versicolor | | 77 | 6.7 | 3.0 | 5.0 | 1.7 | versicolor | | 72 | 6.3 | 2.5 | 4.9 | 1.5 | versicolor | | virginica | 118 | 7.7 | 2.6 | 6.9 | 2.3 | virginica | | 117 | 7.7 | 3.8 | 6.7 | 2.2 | virginica | | 122 | 7.7 | 2.8 | 6.7 | 2.0 | virginica | 매서드는 그룹별 대표값을 만드는 것이 아니라 그룹별 계산을 통해 데이터프레임 자체를 변화시킨다. 따라서 만들어진 데이터프레임의 크기는 원래 데이터프레임과 같다. 예를 들어 다음처럼 각 붓꽃 꽃잎길이가 해당 종 내에서 대/중/소 어느 것에 해당되는지에 대한 데이터프레임을 만들 수도 있다. | | petallength | petallength_class | | --- | --- | --- | | 140 | 5.6 | 중 | | 141 | 5.1 | 소 | | 142 | 5.1 | 소 | | 143 | 5.9 | 대 | | 144 | 5.7 | 중 | | 145 | 5.2 | 소 | | 146 | 5.0 | 소 | | 147 | 5.2 | 소 | | 148 | 5.4 | 중 | | 149 | 5.1 | 소 | Pandas는 명령과 명령의 중간 성격을 가지는 명령도 제공한다. 명령은 명령처럼 그룹분석을 하지만 최종적으로는 명령처럼 피봇테이블을 만든다. 즉 명령의 결과에 을 자동 적용하여 2차원적인 형태로 변형한다. 사용 방법은 다음과 같다. pivottable(data, values=None, index=None, columns=None, aggfunc='mean', fillvalue=None, margins=False, margins_name='All') data: 분석할 데이터프레임 (메서드일 때는 필요하지 않음) values: 분석할 데이터프레임에서 분석할 열 index: 행 인덱스로 들어갈 키 열 또는 키 열의 리스트 columns: 열 인덱스로 들어갈 키 열 또는 키 열의 리스트 aggfunc: 분석 메서드 fill_value: NaN 대체 값 margins: 모든 데이터를 분석한 결과를 오른쪽과 아래에 붙일지 여부 margins_name: 마진 열(행)의 이름 만약 조건에 따른 데이터가 유일하게 선택되지 않으면 그룹연산을 하며 이 때 인수로 정의된 함수를 수행하여 대표값을 계산한다. 를 메서드로 사용할 때는 객체 자체가 데이터가 되므로 인수가 필요하지 않다. 예를 들어 위에서 만들었던 피봇테이블은 명령으로 다음과 같이 만들 수도 있다. 인수의 순서에 주의해야 한다. | 연도 | 2005 | 2010 | 2015 | | --- | --- | --- | --- | | 도시 | | | | | 부산 | 3512547.0 | 3393191.0 | 3448737.0 | | 서울 | 9762546.0 | 9631482.0 | 9904312.0 | | 인천 | NaN | 263203.0 | 2890451.0 | 인수를 주면 로 주어진 분석 방법을 해당 열의 모든 데이터, 해당 행의 모든 데이터 그리고 전체 데이터에 대해 적용한 결과를 같이 보여준다. 가 주어지지 않았으면 평균을 계산한다. | 연도 | 2005 | 2010 | 2015 | 평균 | | --- | --- | --- | --- | --- | | 도시 | | | | | | 부산 | 3512547.0 | 3393191.0 | 3448737.0 | 3.451492e+06 | | 서울 | 9762546.0 | 9631482.0 | 9904312.0 | 9.766113e+06 | | 인천 | NaN | 263203.0 | 2890451.0 | 1.576827e+06 | | 평균 | 6637546.5 | 4429292.0 | 5414500.0 | 5.350809e+06 | 이 결과에서 가장 오른쪽 합계 열의 첫번째 값 3451492은 모든 부산 인구 데이터의 평균, 두번째 값 9766113은 모든 서울 인구 데이터의 평균이다. 가장 아래의 합계 행의 첫번째 값은 2005년 데이터의 평균값, 두번째 값은 2010년 데이터의 평균값이다. 가장 오른쪽 아래의 값 5350809는 전체 데이터의 평균값이다. 다음 계산을 통해 이를 확인할 수 있다. 5350808.625 행 인덱스나 열 인덱스에 리스트를 넣으면 다중 인덱스 테이블을 만든다. | | | 인구 | | --- | --- | --- | | 연도 | 도시 | | | 2005 | 부산 | 3512547 | | 서울 | 9762546 | | 2010 | 부산 | 3393191 | | 서울 | 9631482 | | 인천 | 263203 | | 2015 | 부산 | 3448737 | | 서울 | 9904312 | | 인천 | 2890451 | 식당에서 식사 후 내는 팁(tip)과 관련된 데이터를 이용하여 좀더 구체적으로 그룹분석 방법을 살펴본다. 우선 Seaborn 패키지에 설치된 샘플 데이터를 로드한다. 이 데이터프레임에서 각각의 컬럼은 다음을 뜻한다. total_bill: 식사대금 tip: 팁 sex: 성별 smoker: 흡연/금연 여부 day: 요일 time: 시간 size: 인원 | | total_bill | tip | sex | smoker | day | time | size | | --- | --- | --- | --- | --- | --- | --- | --- | | 239 | 29.03 | 5.92 | Male | No | Sat | Dinner | 3 | | 240 | 27.18 | 2.00 | Female | Yes | Sat | Dinner | 2 | | 241 | 22.67 | 2.00 | Male | Yes | Sat | Dinner | 2 | | 242 | 17.82 | 1.75 | Male | No | Sat | Dinner | 2 | | 243 | 18.78 | 3.00 | Female | No | Thur | Dinner | 2 | 분석의 목표는 식사 대금 대비 팁의 비율이 어떤 경우에 가장 높아지지는 찾는 것이다. 우선 식사대금와 팁의 비율을 나타내는 를 추가하자. | | totalbill | tip | sex | smoker | day | time | size | tippct | | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 239 | 29.03 | 5.92 | Male | No | Sat | Dinner | 3 | 0.203927 | | 240 | 27.18 | 2.00 | Female | Yes | Sat | Dinner | 2 | 0.073584 | | 241 | 22.67 | 2.00 | Male | Yes | Sat | Dinner | 2 | 0.088222 | | 242 | 17.82 | 1.75 | Male | No | Sat | Dinner | 2 | 0.098204 | | 243 | 18.78 | 3.00 | Female | No | Thur | Dinner | 2 | 0.159744 | 다음으로 각 열의 데이터에 대해 간단히 분포를 알아본다. | | totalbill | tip | size | tippct | | --- | --- | --- | --- | --- | | count | 244.000000 | 244.000000 | 244.000000 | 244.000000 | | mean | 19.785943 | 2.998279 | 2.569672 | 0.160803 | | std | 8.902412 | 1.383638 | 0.951100 | 0.061072 | | min | 3.070000 | 1.000000 | 1.000000 | 0.035638 | | 25% | 13.347500 | 2.000000 | 2.000000 | 0.129127 | | 50% | 17.795000 | 2.900000 | 2.000000 | 0.154770 | | 75% | 24.127500 | 3.562500 | 3.000000 | 0.191475 | | max | 50.810000 | 10.000000 | 6.000000 | 0.710345 | 우선 성별로 나누어 데이터 갯수를 세어보자 | | totalbill | tip | smoker | day | time | size | tippct | | --- | --- | --- | --- | --- | --- | --- | --- | | sex | | | | | | | | | Male | 157 | 157 | 157 | 157 | 157 | 157 | 157 | | Female | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 데이터 갯수의 경우 NaN 데이터가 없다면 모두 같은 값이 나올 것이다. 이 때는 명령을 사용하면 더 간단히 표시된다. 명령은 NaN이 있어도 상관하지 않는다. sex Male 157 Female 87 dtype: int64 이번에는 성별과 흡연유무로 나누어 데이터 갯수를 알아보자. sex smoker Male Yes 60 No 97 Female Yes 33 No 54 dtype: int64 좀더 보기 좋게 피봇 테이블 형태로 바꿀 수도 있다. | smoker | Yes | No | All | | --- | --- | --- | --- | | sex | | | | | Male | 60 | 97 | 157 | | Female | 33 | 54 | 87 | | All | 93 | 151 | 244 | 이제 성별과 흡연 여부에 따른 평균 팁 비율을 살펴보자 | | tip_pct | | --- | --- | | sex | | | Male | 0.157651 | | Female | 0.166491 | | | tip_pct | | --- | --- | | smoker | | | Yes | 0.163196 | | No | 0.159328 | 명령을 사용할 수도 있다. | | tip_pct | | --- | --- | | sex | | | Male | 0.157651 | | Female | 0.166491 | | | | tip_pct | | --- | --- | --- | | sex | smoker | | | Male | Yes | 0.152771 | | No | 0.160669 | | Female | Yes | 0.182150 | | No | 0.156921 | | smoker | Yes | No | | --- | --- | --- | | sex | | | | Male | 0.152771 | 0.160669 | | Female | 0.182150 | 0.156921 | 여성 혹은 흡연자의 팁 비율이 높은 것을 볼 수 있다. 하지만 이 데이터에는 평균을 제외한 분산(variance) 등의 다른 통계값이 없으므로 명령으로 여러가지 통계값을 한 번에 알아본다. | | tip_pct | | --- | --- | | | count | mean | std | min | 25% | 50% | 75% | max | | sex | | | | | | | | | | Male | 157.0 | 0.157651 | 0.064778 | 0.035638 | 0.121389 | 0.153492 | 0.186240 | 0.710345 | | Female | 87.0 | 0.166491 | 0.053632 | 0.056433 | 0.140416 | 0.155581 | 0.194266 | 0.416667 | | | tip_pct | | --- | --- | | | count | mean | std | min | 25% | 50% | 75% | max | | smoker | | | | | | | | | | Yes | 93.0 | 0.163196 | 0.085119 | 0.035638 | 0.106771 | 0.153846 | 0.195059 | 0.710345 | | No | 151.0 | 0.159328 | 0.039910 | 0.056797 | 0.136906 | 0.155625 | 0.185014 | 0.291990 | | | | tip_pct | | --- | --- | --- | | | | count | mean | std | min | 25% | 50% | 75% | max | | sex | smoker | | | | | | | | | | Male | Yes | 60.0 | 0.152771 | 0.090588 | 0.035638 | 0.101845 | 0.141015 | 0.191697 | 0.710345 | | No | 97.0 | 0.160669 | 0.041849 | 0.071804 | 0.131810 | 0.157604 | 0.186220 | 0.291990 | | Female | Yes | 33.0 | 0.182150 | 0.071595 | 0.056433 | 0.152439 | 0.173913 | 0.198216 | 0.416667 | | No | 54.0 | 0.156921 | 0.036421 | 0.056797 | 0.139708 | 0.149691 | 0.181630 | 0.252672 | 이번에는 각 그룹에서 가장 많은 팁과 가장 적은 팁의 차이를 알아보자. 이 계산을 해 줄 수 있는 그룹연산 함수가 없으므로 함수를 직접 만들고 메서드를 사용한다. | | | tip | | --- | --- | --- | | sex | smoker | | | Male | Yes | 9.00 | | No | 7.75 | | Female | Yes | 5.50 | | No | 4.20 | 만약 여러가지 그룹연산을 동시에 하고 싶다면 다음과 같이 리스트를 이용한다. | | | total_bill | | --- | --- | --- | | | | mean | peaktopeak | | sex | smoker | | | | Male | Yes | 22.284500 | 43.56 | | No | 19.791237 | 40.82 | | Female | Yes | 17.977879 | 41.23 | | No | 18.105185 | 28.58 | 만약 데이터 열마다 다른 연산을 하고 싶다면 열 라벨과 연산 이름(또는 함수)를 딕셔너리로 넣는다. | | | tippct | totalbill | | --- | --- | --- | --- | | sex | smoker | | | | Male | Yes | 0.152771 | 43.56 | | No | 0.160669 | 40.82 | | Female | Yes | 0.182150 | 41.23 | | No | 0.156921 | 28.58 | 다음은 명령으로 더 복잡한 분석을 한 예이다. | | | size | tip_pct | | --- | --- | --- | --- | | | smoker | Yes | No | Yes | No | | sex | day | | | | | | Male | Thur | 2.300000 | 2.500000 | 0.164417 | 0.165706 | | Fri | 2.125000 | 2.000000 | 0.144730 | 0.138005 | | Sat | 2.629630 | 2.656250 | 0.139067 | 0.162132 | | Sun | 2.600000 | 2.883721 | 0.173964 | 0.158291 | | Female | Thur | 2.428571 | 2.480000 | 0.163073 | 0.155971 | | Fri | 2.000000 | 2.500000 | 0.209129 | 0.165296 | | Sat | 2.200000 | 2.307692 | 0.163817 | 0.147993 | | Sun | 2.500000 | 3.071429 | 0.237075 | 0.165710 | | | | day | Thur | Fri | Sat | Sun | | --- | --- | --- | --- | --- | --- | --- | | time | sex | smoker | | | | | | Lunch | Male | Yes | 23 | 5 | 0 | 0 | | No | 50 | 0 | 0 | 0 | | Female | Yes | 17 | 6 | 0 | 0 | | No | 60 | 3 | 0 | 0 | | Dinner | Male | Yes | 0 | 12 | 71 | 39 | | No | 0 | 4 | 85 | 124 | | Female | Yes | 0 | 8 | 33 | 10 | | No | 2 | 2 | 30 | 43 | 피봇테이블과 그룹연산에 대해 알아 보았다. 분석 연습을 해보기 위해 자주 사용되는 타이타닉 승객데이터를 이용해서 연습 해보면 좋을 것 같다. 출처 : 데이터사이언스 스쿨(http://datascienceschool.net)
2020년 10월 18일32분DataFrame 합성
PythonPandas는 두 개 이상의 DataFrame을 하나로 합치는 데이터 병합(merge)이나 연결(concatenate)을 지원한다. 함수를 사용한 DataFrame 병합 함수는 두 데이터프레임의 공통 열 혹은 인덱스를 기준으로 두 개의 테이블을 합친다. 이 때 기준이 되는 열, 행의 데이터를 키(Key)라고 한다. | 인덱스 | 고객번호 | 이름 | | --- | --- | --- | | 0 | 1001 | 둘리 | | 1 | 1002 | 도우너 | | 2 | 1003 | 또치 | | 3 | 1004 | 길동 | | 4 | 1005 | 마이콜 | | 5 | 1006 | 희동 | | 6 | 1007 | 영희 | | 인덱스 | 고객번호 | 금액 | | --- | --- | --- | | 0 | 1001 | 10000 | | 1 | 1001 | 20000 | | 2 | 1005 | 15000 | | 3 | 1006 | 5000 | | 4 | 1008 | 100000 | | 5 | 1001 | 30000 | 함수로 위의 두 데이터프레임 df1, df2 를 합치면 공통열인 열을 기준으로 데이터를 찾아서 합친다. 이 때 기본적으로는 양쪽 데이터프레임에 모두 키가 존재하는 데이터만 보여주는 inner join 방식을 사용한다. | 인덱스 | 고객번호 | 이름 | 금액 | | --- | --- | --- | --- | | 0 | 1001 | 둘리 | 10000 | | 1 | 1001 | 둘리 | 20000 | | 2 | 1001 | 둘리 | 30000 | | 3 | 1005 | 마이콜 | 15000 | | 4 | 1006 | 희동 | 5000 | outer join 방식은 키 값이 한쪽에만 있어도 데이터를 보여준다. | 인덱스 | 고객번호 | 이름 | 금액 | | --- | --- | --- | --- | | 0 | 1001 | 둘리 | 10000.0 | | 1 | 1001 | 둘리 | 20000.0 | | 2 | 1001 | 둘리 | 30000.0 | | 3 | 1002 | 도우너 | NaN | | 4 | 1003 | 또치 | NaN | | 5 | 1004 | 길동 | NaN | | 6 | 1005 | 마이콜 | 15000.0 | | 7 | 1006 | 희동 | 5000.0 | | 8 | 1007 | 영희 | NaN | | 9 | 1008 | NaN | 100000.0 | left, right 방식은 각각 첫번째, 혹은 두번째 데이터프레임의 키 앖을 모두 보여준다. | 인덱스 | 고객번호 | 이름 | 금액 | | --- | --- | --- | --- | | 0 | 1001 | 둘리 | 10000.0 | | 1 | 1001 | 둘리 | 20000.0 | | 2 | 1001 | 둘리 | 30000.0 | | 3 | 1002 | 도우너 | NaN | | 4 | 1003 | 또치 | NaN | | 5 | 1004 | 길동 | NaN | | 6 | 1005 | 마이콜 | 15000.0 | | 7 | 1006 | 희동 | 5000.0 | | 8 | 1007 | 영희 | NaN | | | 고객번호 | 이름 | 금액 | |---|--------|------|--------| | 0 | 1001 | 둘리 | 10000 | | 1 | 1001 | 둘리 | 20000 | | 2 | 1001 | 둘리 | 30000 | | 3 | 1005 | 마이콜 | 15000 | | 4 | 1006 | 희동 | 5000 | | 5 | 1008 | NaN | 100000 | 만약 테이블에 키 값이 같은 데이터가 여러개 있는 경우에는 있을 수 있는 모든 경우의 수를 따져서 조합을 만들어 낸다. | | 품종 | 꽃잎길이 | |---|---------|--------| | 0 | setosa | 1.4 | | 1 | setosa | 1.3 | | 2 | virginica | 1.5 | | 3 | virginica | 1.3 | | | 품종 | 꽃잎너비 | |---|-----------|--------| | 0 | setosa | 0.4 | | 1 | virginica | 0.3 | | 2 | virginica | 0.5 | | 3 | versicolor| 0.3 | 이 데이터에서 키 값 setosa에 대해 왼쪽 데이터프레임에는 1.4와 1.3 이라는 2개의 데이터, 오른쪽 데이터프레임에는 0.4라는 1개의 데이터가 있으므로 병합된 데이터에는 setosa가 (1.4, 0.4), (1.3, 0.4) 두 개의 데이터가 생긴다. 키값 virginica의 경우에는 왼쪽 데이터프레임에 1.5와 1.3이라는 2개의 데이터, 오른쪽 데이터프레임에 0.3와 0.5라는 2개의 데이터가 있으므로 2개와 2개의 조합에 의해 4가지 값이 생긴다. | | 품종 | 꽃잎길이 | 꽃잎너비 | |---|-----------|--------|--------| | 0 | setosa | 1.4 | 0.4 | | 1 | setosa | 1.3 | 0.4 | | 2 | virginica | 1.5 | 0.3 | | 3 | virginica | 1.5 | 0.5 | | 4 | virginica | 1.3 | 0.3 | | 5 | virginica | 1.3 | 0.5 | 두 데이터프레임에서 이름이 같은 열은 모두 키가 된다. 만약 이름이 같아도 키가 되면 안되는 열이 있다면 인수로 기준열을 명시해야 한다. 다음 예에서 첫번째 데이터프레임의 데이터는 실제로는 금액을 나타내는 데이터 이고 두번째 데이터프레임의 데이터는 실제로 성별을 나타내는 데이터이므로 이름이 같아도 다른 데이터이다. 따라서 이 열은 기준열이 되면 안된다. | | 고객명 | 날짜 | 데이터 | |---|-------|------------|--------| | 0 | 춘향 | 2018-01-01 | 20000 | | 1 | 춘향 | 2018-01-02 | 30000 | | 2 | 몽룡 | 2018-01-01 | 100000 | | | 고객명 | 데이터 | |---|-------|--------| | 0 | 춘향 | 여자 | | 1 | 몽룡 | 남자 | | | 고객명 | 날짜 | 데이터x | 데이터y | |---|-------|------------|----------|----------| | 0 | 춘향 | 2018-01-01 | 20000 | 여자 | | 1 | 춘향 | 2018-01-02 | 30000 | 여자 | | 2 | 몽룡 | 2018-01-01 | 100000 | 남자 | 이 때 기준 열이 아니면서 이름이 같은 열에는 또는 와 같은 접미사가 붙는다. 반대로 키가 되는 기준열의 이름이 두 데이터프레임에서 다르면 , 인수를 사용하여 기준열을 명시해야 한다. | | 이름 | 성정 | |---|------|------| | 0 | 영희 | 1 | | 1 | 철수 | 2 | | 2 | 철수 | 3 | | | 성명 | 성적2 | |---|------|-------| | 0 | 영희 | 4 | | 1 | 영희 | 5 | | 2 | 철수 | 6 | | | 이름 | 성정 | 성명 | 성적2 | |---|------|------|------|-------| | 0 | 영희 | 1 | 영희 | 4 | | 1 | 영희 | 1 | 영희 | 5 | | 2 | 철수 | 2 | 철수 | 6 | | 3 | 철수 | 3 | 철수 | 6 | 일반 데이터 열이 아닌 인덱스를 기준열로 사용하여면 또는 인수를 로 설정한다. | | 도시 | 연도 | 인구 | |---|------|------|----------| | 0 | 서울 | 2000 | 9853972 | | 1 | 서울 | 2005 | 9762546 | | 2 | 서울 | 2010 | 9631482 | | 3 | 부산 | 2000 | 3655437 | | 4 | 부산 | 2005 | 3512547 | | | | 데이터1 | 데이터2 | |---|-----|---------|---------| | 부산 | 2000 | 0 | 1 | | 부산 | 2005 | 2 | 3 | | 서울 | 2000 | 4 | 5 | | 서울 | 2005 | 6 | 7 | | 서울 | 2010 | 8 | 9 | | 서울 | 2015 | 10 | 11 | | | 도시 | 연도 | 인구 | 데이터1 | 데이터2 | |---|------|------|----------|---------|---------| | 0 | 서울 | 2000 | 9853972 | 4 | 5 | | 1 | 서울 | 2005 | 9762546 | 6 | 7 | | 2 | 서울 | 2010 | 9631482 | 8 | 9 | | 3 | 부산 | 2000 | 3655437 | 0 | 1 | | 4 | 부산 | 2005 | 3512547 | 2 | 3 | | | 서울 | 부산 | |---|------|------| | a | 1.0 | 2.0 | | c | 3.0 | 4.0 | | e | 5.0 | 6.0 | | | 대구 | 광주 | |---|-------|-------| | b | 7.0 | 8.0 | | c | 9.0 | 10.0 | | d | 11.0 | 12.0 | | e | 13.0 | 14.0 | | | 서울 | 부산 | 대구 | 광주 | |---|-------|-------|-------|-------| | a | 1.0 | 2.0 | NaN | NaN | | b | NaN | NaN | 7.0 | 8.0 | | c | 3.0 | 4.0 | 9.0 | 10.0 | | d | NaN | NaN | 11.0 | 12.0 | | e | 5.0 | 6.0 | 13.0 | 14.0 | join 매서드 명령어 대신 매서드를 사용할 수도 있다. | | 서울 | 부산 | 대구 | 광주 | |---|-------|-------|-------|-------| | a | 1.0 | 2.0 | NaN | NaN | | b | NaN | NaN | 7.0 | 8.0 | | c | 3.0 | 4.0 | 9.0 | 10.0 | | d | NaN | NaN | 11.0 | 12.0 | | e | 5.0 | 6.0 | 13.0 | 14.0 | 함수를 사용한 데이터 연결 함수를 사용하면 기준 열(key column)을 사용하지 않고 단순히 데이터를 연결(concatenate)한다. 기본적으로는 위/아래로 데이터 행을 연결한다. 단순히 두 시리즈나 데이터프레임을 연결하기 때문에 인덱스 값이 중복될 수 있다. A 0 B 1 dtype: int64 A 2 B 3 C 4 dtype: int64 A 0 B 1 A 2 B 3 C 4 dtype: int64 내부적으로 기본값은 이기 때문에 만약 옆으로 데이터 열을 연결하고 싶으면 로 인수를 설정한다. | | 데이터1 | 데이터2 | |---|---------|---------| | a | 0 | 1 | | b | 2 | 3 | | c | 4 | 5 | | | 데이터3 | 데이터4 | |---|---------|---------| | a | 5 | 6 | | c | 7 | 8 | | | 데이터1 | 데이터2 | 데이터3 | 데이터4 | |---|---------|---------|---------|---------| | a | 0 | 1 | 5.0 | 6.0 | | b | 2 | 3 | NaN | NaN | | c | 4 | 5 | 7.0 | 8.0 | 출처 : 데이터사이언스 스쿨(http://datascienceschool.net)
2020년 10월 09일14분DataFrame 인덱스 조작
PythonDataFrame 인덱스 설정 및 제거 DataFrame에 인덱스로 들어가 있어야 할 데이터가 일반 데이터 열에 들어가 있거나 반대로 일반 데이터 열이어야 할 것이 인덱스로 되어 있을 수 있다. 이 때는 명령이나 명령으로 인덱스와 일반 데이터 열을 교환할 수 있다. set_index : 기존의 행 인덱스를 제거하고 데이터 열 중 하나를 인덱스로 설정 reset_index : 기존의 행 인덱스를 제거하고 인덱스를 데이터 열로 추가 array([['A', 'B', 'C', 'D', 'E'], ['0.67', '0.21', '0.13', '0.32', '0.36'], ['0.57', '0.44', '0.99', '0.1', '0.21'], ['0.16', '0.65', '0.25', '0.47', '0.24']], dtype='U32') | index | C1 | C2 | C3 | C4 | |-------|----|----|----|----| | 0 | A | 0.55 | 0.65 | 0.79 | | 1 | B | 0.72 | 0.44 | 0.53 | | 2 | C | 0.6 | 0.89 | 0.57 | | 3 | D | 0.54 | 0.96 | 0.93 | | 4 | E | 0.42 | 0.38 | 0.07 | 명령으로 C1열을 인덱스로 설정할 수 있다. 이때 기존 인덱스는 없어진다. | C1 | C2 | C3 | C4 | |----|----|----|----| | A | 0.55 | 0.65 | 0.79 | | B | 0.72 | 0.44 | 0.53 | | C | 0.6 | 0.89 | 0.57 | | D | 0.54 | 0.96 | 0.93 | | E | 0.42 | 0.38 | 0.07 | 마찬가지로 C2열을 인덱스로 지정하면 기존의 인덱스는 사라진다. | C2 | C3 | C4 | |----|----|----| | 0.55 | 0.65 | 0.79 | | 0.72 | 0.44 | 0.53 | | 0.6 | 0.89 | 0.57 | | 0.54 | 0.96 | 0.93 | | 0.42 | 0.38 | 0.07 | 명령으로 인덱스를 보통의 자료형으로 바꿀 수도 있다. 이 때 인덱스 열은 자료형의 가장 선두로 삽입된다. DataFrame의 인덱스는 정수로 된 디폴트 인덱스로 바뀌게 된다. | index | C1 | C2 | C3 | C4 | |-------|----|----|----|----| | 0 | A | 0.55 | 0.65 | 0.79 | | 1 | B | 0.72 | 0.44 | 0.53 | | 2 | C | 0.6 | 0.89 | 0.57 | | 3 | D | 0.54 | 0.96 | 0.93 | | 4 | E | 0.42 | 0.38 | 0.07 | 명령 사용시에 로 설정하면 인덱스 열을 보통의 자료열로 올리는 것이 아니라 그냥 버리게 된다. | index | C2 | C3 | C4 | |-------|----|----|----| | 0 | 0.55 | 0.65 | 0.79 | | 1 | 0.72 | 0.44 | 0.53 | | 2 | 0.6 | 0.89 | 0.57 | | 3 | 0.54 | 0.96 | 0.93 | | 4 | 0.42 | 0.38 | 0.07 | 다중 인덱스 행이나 열에 여러 계층을 가지는 인덱스 즉, 다중 인덱스(multi-index)를 설정할 수도 있다. DataFrame을 생성할 때 인수에 다음 예제처럼 리스트의 리스트(행렬) 형태로 인덱스를 넣으면 다중 열 인덱스를 가지게 된다. | index | AC1 | AC2 | BC1 | BC2 | |-------|------|------|------|------| | 0 | 1.76 | 0.40 | 0.98 | 2.24 | | 1 | 1.87 | -0.98 | 0.95 | -0.15 | | 2 | -0.10 | 0.41 | 0.14 | 1.45 | | 3 | 0.76 | 0.12 | 0.44 | 0.33 | | 4 | 1.49 | -0.21 | 0.31 | -0.85 | 다중 인덱스는 이름을 지정하면 더 편리하게 사용할 수 있다. 열 인덱스들의 이름 지정은 객체의 속성에 리스트를 넣어서 지정한다. | Cidx1 | AC1 | AC2 | BC1 | BC2 | |-------|------|------|------|------| | 0 | 1.76 | 0.40 | 0.98 | 2.24 | | 1 | 1.87 | -0.98 | 0.95 | -0.15 | | 2 | -0.10 | 0.41 | 0.14 | 1.45 | | 3 | 0.76 | 0.12 | 0.44 | 0.33 | | 4 | 1.49 | -0.21 | 0.31 | -0.85 | 마찬가지로 DataFrame을 생성할 때 인수에 리스트의 리스트(행렬) 형태로 인덱스를 넣으면 다중 (행) 인덱스를 가진다. 행 인덱스들의 이름 지정은 객체의 속성에 리스트를 넣어서 지정한다. | Ridx1 | Ridx2 | AC | AD | BC | BD | |-------|-------|------|------|------|------| | M | id_1 | 1.76 | 0.40 | 0.98 | 2.24 | | M | id_2 | 1.87 | -0.98 | 0.95 | -0.15 | | M | id_3 | -0.10 | 0.41 | 0.14 | 1.45 | | F | id_1 | 0.76 | 0.12 | 0.44 | 0.33 | | F | id_2 | 1.49 | -0.21 | 0.31 | -0.85 | | F | id_3 | -2.55 | 0.65 | 0.86 | -0.74 | 행 인덱스와 열 인덱스 교환 명령이나 명령을 쓰면 열 인덱스를 행 인덱스로 바꾸거나 반대로 행 인덱스를 열 인덱스로 바꿀 수 있다. : 열 인덱스 -> 행 인덱스로 변환 : 행 인덱스 -> 열 인덱스로 변환 명령을 실행하면 열 인덱스가 반시계 방향으로 90도 회전한 것과 비슷한 모양이 된다. 마찬가지로 unstack 명령을 실행하면 행 인덱스가 시계 방향으로 90도 회전한 것과 비슷하다. 인덱스를 지정할 때는 문자열 이름과 순서를 표시하는 숫자 인덱스를 모두 사용할 수 있다. | Ridx1 | Ridx2 | Cidx1 | C | D | |-------|-------|--------|----|----| | M | id_1 | A | 1.76 | 0.40 | | M | id_1 | B | 0.98 | 2.24 | | M | id_2 | A | 1.87 | -0.98 | | M | id_2 | B | 0.95 | -0.15 | | M | id_3 | A | -0.10 | 0.41 | | M | id_3 | B | 0.14 | 1.45 | | F | id_1 | A | 0.76 | 0.12 | | F | id_1 | B | 0.44 | 0.33 | | F | id_2 | A | 1.49 | -0.21 | | F | id_2 | B | 0.31 | -0.85 | | F | id_3 | A | -2.55 | 0.65 | | F | id_3 | B | 0.86 | -0.74 | | Ridx1 | Ridx2 | Cidx2 | A | B | |-------|-------|--------|----|----| | M | id_1 | C | 1.76 | 0.98 | | M | id_1 | D | 0.40 | 2.24 | | M | id_2 | C | 1.87 | 0.95 | | M | id_2 | D | -0.98 | -0.15 | | M | id_3 | C | -0.10 | 0.14 | | M | id_3 | D | 0.41 | 1.45 | | F | id_1 | C | 0.76 | 0.44 | | F | id_1 | D | 0.12 | 0.33 | | F | id_2 | C | 1.49 | 0.31 | | F | id_2 | D | -0.21 | -0.85 | | F | id_3 | C | -2.55 | 0.86 | | F | id_3 | D | 0.65 | -0.74 | | Ridx1 | ACid1 | ACid2 | ACid3 | ADid1 | ADid2 | ADid3 | BCid1 | BCid2 | BCid3 | BDid1 | BDid2 | BDid3 | |-------|----------|----------|----------|----------|----------|----------|----------|----------|----------|----------|----------|----------| | F | 0.76 | 1.49 | -2.55 | 0.12 | -0.21 | 0.65 | 0.44 | 0.31 | 0.86 | 0.33 | -0.85 | -0.74 | | M | 1.76 | 1.87 | -0.10 | 0.40 | -0.98 | 0.41 | 0.98 | 0.95 | 0.14 | 2.24 | -0.15 | 1.45 | | Ridx2 | ACF | ACM | ADF | ADM | BCF | BCM | BDF | BDM | |-------|--------|--------|--------|--------|--------|--------|--------|--------| | id_1 | 0.76 | 1.76 | 0.12 | 0.40 | 0.44 | 0.98 | 0.33 | 2.24 | | id_2 | 1.49 | 1.87 | -0.21 | -0.98 | 0.31 | 0.95 | -0.85 | -0.15 | | id_3 | -2.55 | -0.10 | 0.65 | 0.41 | 0.86 | 0.14 | -0.74 | 1.45 | 다중 인덱스가 있는 경우 인덱싱 DataFrame이 다중 인덱스를 가지는 경우에는 인덱스가 하나의 라벨이나 숫자가 아니라 로 둘러싸인 튜플이 되어야 한다. 예를 들어 앞에서 만든 DataFrame의 경우 다음과 같이 인덱싱할 수 있다. | index | AC1 | AC2 | BC1 | BC2 | |-------|------|------|------|------| | 0 | 1.76 | 0.40 | 0.98 | 2.24 | | 1 | 1.87 | -0.98 | 0.95 | -0.15 | | 2 | -0.10 | 0.41 | 0.14 | 1.45 | | 3 | 0.76 | 0.12 | 0.44 | 0.33 | | 4 | 1.49 | -0.21 | 0.31 | -0.85 | 0 0.98 1 0.95 2 0.14 3 0.44 4 0.31 Name: (B, C1), dtype: float64 0.98 | index | AC1 | AC2 | BC1 | BC2 | |-------|------|------|------|------| | 0 | 1.76 | 0.40 | 100.00 | 2.24 | | 1 | 1.87 | -0.98 | 0.95 | -0.15 | | 2 | -0.10 | 0.41 | 0.14 | 1.45 | | 3 | 0.76 | 0.12 | 0.44 | 0.33 | | 4 | 1.49 | -0.21 | 0.31 | -0.85 | 만약 하나의 레벨 값만 넣으면 다중 인덱스 중에서 가장 상위의 값을 지정한 것으로 본다. | Cidx2 | C1 | C2 | |-------|----|----| | 0 | 1.76 | 0.40 | | 1 | 1.87 | -0.98 | | 2 | -0.10 | 0.41 | | 3 | 0.76 | 0.12 | | 4 | 1.49 | -0.21 | DataFrame은 다음과 같이 인덱싱할 수 있다. | Ridx1 | Ridx2 | AC | AD | BC | BD | |-------|-------|------|------|------|------| | M | id_1 | 1.76 | 0.40 | 0.98 | 2.24 | | M | id_2 | 1.87 | -0.98 | 0.95 | -0.15 | | M | id_3 | -0.10 | 0.41 | 0.14 | 1.45 | | F | id_1 | 0.76 | 0.12 | 0.44 | 0.33 | | F | id_2 | 1.49 | -0.21 | 0.31 | -0.85 | | F | id_3 | -2.55 | 0.65 | 0.86 | -0.74 | Ridx1 Ridx2 M id_1 1.76 id_2 1.87 id_3 -0.10 F id_1 0.76 id_2 1.49 id_3 -2.55 Name: (A, C), dtype: float64 Cidx1 Cidx2 A C 1.76 D 0.40 B C 0.98 D 2.24 Name: (M, id_1), dtype: float64 | | Cidx1 | A | B | |----|-------|--------------------|--------------------| | | Cidx2 | C | D | C | D | |----|-------|----------|----------|----------|----------| | Ridx1 | Ridx2 | | | | | |----|-------|----------|----------|----------|----------| | M | id_1 | 1.76 | 0.40 | 0.98 | 2.24 | | | id_2 | 1.87 | -0.98 | 0.95 | -0.15 | | | id_3 | -0.10 | 0.41 | 0.14 | 1.45 | | F | id_1 | 0.76 | 0.12 | 0.44 | 0.33 | | | id_2 | 1.49 | -0.21 | 0.31 | -0.85 | | | id_3 | -2.55 | 0.65 | 0.86 | -0.74 | | All | All | 6.46 | 0.78 | 7.36 | 4.56 | 다중 인덱스의 인덱스 순서 교환 다중 인덱스의 인덱스 순서를 바꾸고 싶으면 명령을 사용한다. ijaxissort_indexlevel` 인수를 사용하여 어떤 인덱스를 기준으로 정렬하는지 알려주어야 한다. | | Cidx2 | C | D | C | D | |----|---------|----------|----------|----------|----------| | | Cidx1 | A | A | B | B | |----|---------|----------|----------|----------|----------| | Ridx2 | Ridx1 | | | | | |----|---------|----------|----------|----------|----------| | All | All | 6.46 | 0.78 | 7.36 | 4.56 | | id_1 | F | 0.76 | 0.12 | 0.44 | 0.33 | | id_1 | M | 1.76 | 0.40 | 0.98 | 2.24 | | id_2 | F | 1.49 | -0.21 | 0.31 | -0.85 | | id_2 | M | 1.87 | -0.98 | 0.95 | -0.15 | | id_3 | F | -2.55 | 0.65 | 0.86 | -0.74 | | id_3 | M | -0.10 | 0.41 | 0.14 | 1.45 | | | Cidx2 | A | B | A | B | |----|---------|----------|----------|----------|----------| | | Cidx1 | C | D | C | D | |----|---------|----------|----------|----------|----------| | Ridx1 | Ridx2 | | | | | |----|---------|----------|----------|----------|----------| | All | All | 6.46 | 7.36 | 0.78 | 4.56 | | id_1 | F | 0.76 | 0.44 | 0.12 | 0.33 | | id_1 | M | 1.76 | 0.98 | 0.40 | 2.24 | | id_2 | F | 1.49 | 0.31 | -0.21 | -0.85 | | id_2 | M | 1.87 | 0.95 | -0.98 | -0.15 | | id_3 | F | -2.55 | 0.86 | 0.65 | -0.74 | | id_3 | M | -0.10 | 0.14 | 0.41 | 1.45 | 출처 : 데이터사이언스 스쿨(datascienceschool.net)
2020년 10월 06일16분Pandas DataFrame 데이터 조작
PythonPandas는 Numpy의 2차원 배열에서 가능한 대부분의 데이터 처리가 가능하며 추가로 데이터 처리 및 변환을 위한 다양한 함수와 메서드를 제공한다. 데이터 갯수 세기 가장 간단한 데이터 분석은 데이터의 갯수를 세는 것이나. 메서드를 사용하는데, 주의할 점은 NaN값은 세지 않는다는 것이다. 0 0.0 1 1.0 2 2.0 3 NaN 4 4.0 5 5.0 6 6.0 7 7.0 8 8.0 9 9.0 dtype: float64 9 데이터프레임에서는 각 열마다 별도로 데이터 갯수를 센다. 데이터에서 값이 누락된 부분을 찾을 때 유용하다. | index | 0 | 1 | 2 | 3 | |-------|----|----|----|----| | 0 | 0.0 | 0.0 | 3.0 | 2.0 | | 1 | 3.0 | 0.0 | 2.0 | 1.0 | | 2 | 3.0 | 2.0 | 4.0 | NaN | | 3 | 4.0 | 3.0 | 4.0 | 2.0 | 0 4 1 4 2 4 3 3 dtype: int64 카테고리 값 세기 Series의 값이 정수, 문자열, 카테고리 값인 경우에는 value_counts 매서드로 각각의 값이 나온 횟수를 셀 수 있다. 95 4 96 5 97 2 98 4 99 3 dtype: int32 1 22 0 18 4 17 5 16 3 14 2 13 dtype: int64 DataFrame에는 매서드가 없으므로 각 열마다 별도 확인 해야 한다. 3.0 2 4.0 1 0.0 1 Name: 0, dtype: int64 정렬 데이터를 정렬하려면 와 매서드를 사용한다. 는 인덱스 값을 기준으로, 는 데이터 값을 기준으로 정렬한다. 앞서 Series의 각 데이터 값에 따른 데이터 갯수를 보기좋게 정렬하려면 를 사용한다. 0 18 1 22 2 13 3 14 4 17 5 16 dtype: int64 NaN값이 있는 경우에는 정렬하면 NaN값은 마지막에 위치한다. 0 0.0 1 1.0 2 2.0 4 4.0 5 5.0 6 6.0 7 7.0 8 8.0 9 9.0 3 NaN dtype: float64 큰 수에서 작은 수로 반대방향 정렬하려면 인수를 지정한다. 9 9.0 8 8.0 7 7.0 6 6.0 5 5.0 4 4.0 2 2.0 1 1.0 0 0.0 3 NaN dtype: float64 DataFrame에서 매서드를 사용하려면 인수로 정렬 기준이 되는 열을 지정해 주어야 한다. | index | 0 | 1 | 2 | 3 | |-------|----|----|----|----| | 0 | 0.0 | 0.0 | 3.0 | 2.0 | | 1 | 3.0 | 0.0 | 2.0 | 1.0 | | 2 | 3.0 | 2.0 | 4.0 | NaN | | 3 | 4.0 | 3.0 | 4.0 | 2.0 | 인수에 리스트 값을 넣으면 이 순서대로 정렬 기준이 우선순위가 된다. | index | 0 | 1 | 2 | 3 | |-------|----|----|----|----| | 1 | 3.0 | 0.0 | 2.0 | 1.0 | | 0 | 0.0 | 0.0 | 3.0 | 2.0 | | 2 | 3.0 | 2.0 | 4.0 | NaN | | 3 | 4.0 | 3.0 | 4.0 | 2.0 | 행/열 합계 행과 열의 합계를 구할 때는 매서드를 사용한다. 행 합계 : axis=1 열 합계 : axis=0 (기본값이므로 생략 가능) | index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |-------|----|----|----|----|----|----|----|----| | 0 | 5 | 8 | 9 | 5 | 0 | 0 | 1 | 7 | | 1 | 6 | 9 | 2 | 4 | 5 | 2 | 4 | 2 | | 2 | 4 | 7 | 7 | 9 | 1 | 7 | 0 | 6 | | 3 | 9 | 9 | 7 | 6 | 9 | 1 | 0 | 1 | 0 35 1 34 2 41 3 42 dtype: int64 0 24 1 33 2 25 3 24 4 15 5 10 6 5 7 16 dtype: int64 행과 열의 합을 행/열에 추가해보자. | index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | row_sum | |-------|----|----|----|----|----|----|----|----|---------| | 0 | 5 | 8 | 9 | 5 | 0 | 0 | 1 | 7 | 35 | | 1 | 6 | 9 | 2 | 4 | 5 | 2 | 4 | 2 | 34 | | 2 | 4 | 7 | 7 | 9 | 1 | 7 | 0 | 6 | 41 | | 3 | 9 | 9 | 7 | 6 | 9 | 1 | 0 | 1 | 42 | | index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | row_sum | |-------|----|----|----|----|----|----|----|----|---------| | 0 | 5.0 | 8.0 | 9.0 | 5.0 | 0.0 | 0.0 | 1.0 | 7.0 | 35.0 | | 1 | 6.0 | 9.0 | 2.0 | 4.0 | 5.0 | 2.0 | 4.0 | 2.0 | 34.0 | | 2 | 4.0 | 7.0 | 7.0 | 9.0 | 1.0 | 7.0 | 0.0 | 6.0 | 41.0 | | 3 | 9.0 | 9.0 | 7.0 | 6.0 | 9.0 | 1.0 | 0.0 | 1.0 | 42.0 | | col_sum | 24.0 | 33.0 | 25.0 | 24.0 | 15.0 | 10.0 | 5.0 | 16.0 | 152.0 | apply 변환 행이나 열 단위로 더 복잡한 처리를 하고 싶을 때는 매서드를 사용한다. 인수로 행 또는 열을 받는 함수를 매서드의 인수로 넣으면 각 열(또는 행)을 반복하여 그 함수에 적용시킨다. | index | A | B | C | |-------|----|----|----| | 0 | 1 | 2 | 1 | | 1 | 3 | 3 | 5 | | 2 | 4 | 1 | 2 | | 3 | 3 | 2 | 4 | | 4 | 4 | 3 | 4 | 예를 들어 각 열의 최대값과 최소값의 차이를 구하고 싶으면 다음과 같은 람다 함수를 넣는다. A 3 B 2 C 4 dtype: int64 마찬가지로 행에 대해 적용하고 싶다면 인수를 추가해 주면 된다. 0 1 1 2 2 3 3 2 4 1 dtype: int64 각 열에 대해 어떤값이 얼마나 사용되고 있는지 알고 싶다면 함수를 넣을 수도 있다. | index | A | B | C | |-------|----|----|----| | 1 | 1.0 | 1.0 | 1.0 | | 2 | NaN | 2.0 | 1.0 | | 3 | 2.0 | 2.0 | NaN | | 4 | 2.0 | NaN | 2.0 | | 5 | NaN | NaN | 1.0 | NaN 값은 fillna 매서드를 사용하여 원하는 값으로 바꿀 수 있다. astype 매서드로 전체 데이터의 자료형을 바꾸는 것도 가능하다. | index | A | B | C | |-------|----|----|----| | 1 | 1 | 1 | 1 | | 2 | 0 | 2 | 1 | | 3 | 2 | 2 | 0 | | 4 | 2 | 0 | 2 | | 5 | 0 | 0 | 1 | 실수 값을 카테고리 값으로 변환 실수 값을 크기 기준으로 하여 카테고리 값으로 변환하고 싶을 때는 다음과 같은 명령을 사용한다. cut : 실수 값의 경계선을 지정하는 경우 qcut : 갯수가 똑같은 구간으로 나누는 경우 명령을 사용하면 실수값을 다음처럼 카테고리 값으로 바꿀 수 있다. 인수는 카테고리를 나누는 기준값이 된다. 영역을 넘는 값은 NaN으로 처리된다. [NaN, '미성년자', '미성년자', '청년', '청년', ..., '노년', '청년', '장년', '중년', NaN] Length: 12 Categories (5, object): ['미성년자' < '청년' < '중년' < '장년' < '노년'] 명령이 반환하는 값은 클래스 객체이다. 이 객체는 속성으로 라벨 문자열을, 속성으로 정수로 인코딩한 카테고리 값을 가진다. pandas.core.arrays.categorical.Categorical Index(['미성년자', '청년', '중년', '장년', '노년'], dtype='object') array([-1, 0, 0, 1, 1, 3, 2, 4, 1, 3, 2, -1], dtype=int8) | index | ages | age_cat | |-------|------|----------| | 0 | 0 | NaN | | 1 | 2 | 미성년자 | | 2 | 10 | 미성년자 | | 3 | 21 | 청년 | | 4 | 23 | 청년 | | 5 | 37 | 장년 | | 6 | 31 | 중년 | | 7 | 61 | 노년 | | 8 | 20 | 청년 | | 9 | 41 | 장년 | | 10 | 32 | 중년 | | 11 | 100 | NaN | 정말 쉽게 데이터를 정의한 카테고리기준으로 분류 하였다! 명령은 구각 경계선을 지정하지 않고 데이터 갯수가 같도록 지정한 수의 구간으로 나눈다. 예를 들어 다음 코드는 1000개의 데이터를 4개의 구간으로 나누는데 각 구간은 250개씩 데이터를 가진다. ['Q2', 'Q1', 'Q2', 'Q3', 'Q1', ..., 'Q1', 'Q1', 'Q4', 'Q4', 'Q2'] Length: 1000 Categories (4, object): ['Q1' < 'Q2' < 'Q3' < 'Q4'] Q4 250 Q3 250 Q2 250 Q1 250 dtype: int64 성적을 비유하여 생각해보면 은 절대평가 기준이 되는 점수에 의해 분류가 되는 것이고 은 상대평가 즉 점수의 순서대로 정렬하고 특정 수만큼씩 분류하는 것이라고 생각하면 될듯 싶다. 출처 : 데이터사이언스 스쿨(datascienceschool.net)
2020년 10월 03일12분Pandas DataFrame 인덱싱
PythonDataFrame 인덱싱 DataFrame에서 특정한 데이터만 골라내는 것을 인덱싱(indexing)이라고 한다. Pandas는 numpy행렬과 같이 쉼표를 사용한 형식의 2차원 인덱싱을 지원하기 위해 다음과 같은 특별한 인덱서(indexer) 속성을 제공한다. loc : 라벨값 기반의 2차원 인덱싱 iloc : 순서를 나타내는 정수 기반의 2차원 인덱싱 at : 라벨값 기반의 2차원 인덱싱 (한개의 스카라 값만 찾는다.) iat : 순서를 나타내는 정수 기반의 2차원 인덱싱 (한개의 스칼라 값만 찾는다.) loc 인덱서 또는 이때 인덱싱 값은 다음중 하나이다. 행 인덱싱값은 정수 또는 행 인덱스데이터 이고 열 인덱싱값은 라벨 문자열 이다. 인덱스데이터 인덱스데이터 슬라이스 인덱스데이터 리스트 같은 행 인덱스를 가지는 Boolean 시리즈 (행 인덱싱의 경우) 위의 값들을 반환하는 함수 글로 정의를 하자니 확 와닿지가 않는다. 데이터 프레임을 예로 들어 살펴보자. | index | A | B | C | D | |-------|----|----|----|----| | a | 10 | 11 | 12 | 13 | | b | 14 | 15 | 16 | 17 | | c | 18 | 19 | 20 | 21 | 인덱싱값을 하나만 받는 경우 만약 인덱서를 사용하면서 인덱스를 하나만 넣으면 행을 선택한다. 인덱스데이터가 "a"인 행을 고르면 행이 Series로 출력된다. Series로 항하로 길게 출력되긴하지만 데이터를 보면 행의 데이터를 가져오고 있다. A 10 B 11 C 12 D 13 Name: a, dtype: int32 인덱스데이터 슬라이스 | index | A | B | C | D | |-------|----|----|----|----| | b | 14 | 15 | 16 | 17 | | c | 18 | 19 | 20 | 21 | | index | A | B | C | D | |-------|----|----|----|----| | b | 14 | 15 | 16 | 17 | | c | 18 | 19 | 20 | 21 | 인덱스데이터의 리스트도 가능하다. | index | A | B | C | D | |-------|----|----|----|----| | b | 14 | 15 | 16 | 17 | | c | 18 | 19 | 20 | 21 | 인덱스를 가지는 Boolean Series도 행을 선택하는 인덱싱 값으로 쓸 수 있다. a False b False c True Name: A, dtype: bool | index | A | B | C | D | |-------|----|----|----|----| | c | 18 | 19 | 20 | 21 | 함수를 사용할 수도 있다. a False b False c True Name: A, dtype: bool | index | A | B | C | D | |-------|----|----|----|----| | c | 18 | 19 | 20 | 21 | 인덱서가 없는 경우에 사용했던 라벨 인덱싱이나 라벨 리스트 인덱싱은 불가능하다. 원래 행 인덱스값이 정수인 경우에는 슬라이싱도 라벨 슬라이싱 방식을 따른다. | index | A | B | C | D | |-------|----|----|----|----| | 0 | 10 | 11 | 12 | 13 | | 1 | 14 | 15 | 16 | 17 | | 2 | 18 | 19 | 20 | 21 | | 3 | 22 | 23 | 24 | 25 | | index | A | B | C | D | |-------|----|----|----|----| | 1 | 14 | 15 | 16 | 17 | | 2 | 18 | 19 | 20 | 21 | 위 내용을 표로 정리하면, | 인덱싱 값 | 가능 | 결과 | 자료형 | 추가사항 | | :------------------------- | :--: | :--: | :----------- | :-------------------------------------------------------- | | 행 인덱스값(정수) | O | 행 | 시리즈 | | | 행 인덱스값(정수) 슬라이스 | O | 행 | 데이터프레임 | 가 없는 경우와 같음 | | 행 인덱스값(정수) 리스트 | O | 행 | 데이터프레임 | | | Boolean Series | O | 행 | 데이터프레임 | 시리즈의 인덱스가 데이터프레임의 행 인덱스와 같아야 한다. | | Boolean Series 반환 함수 | O | 행 | 데이터프레임 | | | 열 라벨 | X | | | 가 없는 경우에만 쓸 수 있다. | | 열 라벨 리스트 | X | | | 가 없는 경우에만 쓸 수 있다. | 인덱싱값을 행과 열 모두 받는 경우 인덱싱값을 행과 열 모두 받으려면 와 같은 형태로 사용한다. 행 인덱스 라벨값이 , 열 인덱스 라벨값이 인 위치의 값을 구해보자. 10 인덱싱값으로 라벨 데이터의 슬라이싱 또는 리스트를 사용할 수도 있다. b 14 c 18 Name: A, dtype: int32 A 10 B 11 C 12 D 13 Name: a, dtype: int32 | index | B | D | |-------|----|----| | a | 11 | 13 | | b | 15 | 17 | 행 인덱스가 같은 Boolean Series 이러한 Boolean Series 반환하는 함수도 행의 인덱싱 값이 될 수 있다. | index | C | D | |-------|----|----| | b | 16 | 17 | | c | 20 | 21 | iloc 인덱서 인덱서는 인덱서와 반대로 라벨이 아니라 순서를 나타내는 정수 인덱스만 받는다. 다른 사항은 인덱서와 같다. 11 a 12 b 16 Name: C, dtype: int32 인덱서와 마찬가지로 인덱스가 하나만 들어가면 행을 선택한다. A 18 B 19 C 20 D 21 Name: c, dtype: int32 | index | A | B | C | D | |-------|----|----|----|----| | a | 10 | 11 | 12 | 13 | | b | 14 | 15 | 16 | 17 | | c | 72 | 76 | 80 | 84 | at, iat 인덱서 , 인덱서는 , 'iloc` 인덱서와 비슷하지만 하나의 스칼라 값을 뽑을 때만 사용한다. 하여 빠른 인덱싱 속도가 요구되는 경우에 사용한다. 5.62 µs ± 87.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) 3.11 µs ± 29.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) 16.8 µs ± 462 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) 14.8 µs ± 262 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) 출처 : 데이터사이언스 스쿨(datascienceschool.net)
2020년 10월 01일9분Pandas 데이터 입출력
Python데이터 입출력 Pandas는 데이터 파일을 읽어 데이터프레임으로 만들 수 있다. 다음처럼 여러 포맷을 지원한다. CSV EXCEL HTML JSON HDFS SAS STATA SQL 이중에서 가장 단순하지만 널리 사용되는 CSV(Comma Separated Values) 포맷 입출력에 대해 살펴보자. %%writefile 명령 샘플 데이터로 사용할 CSV 파일을 %%writefile 매직 명령으로 만들어보자. Overwriting sample1.csv CSV 파일 입력 | index | c1 | c2 | c3 | |-------|----|----|-----| | 0 | 1 | 1.11 | one | | 1 | 2 | 2.22 | two | | 2 | 3 | 3.33 | three | 위에서 읽은 데이터에는 열 인덱스는 있지만 행 인덱스 정보가 없으므로 0부터 시작하는 정수 인덱스가 자동으로 추가되었다. 만야그 위의 경우와 달리 데이터 파일에 열 인덱스 정보가 없는 경우에는 명령의 인수로 설정할 수 있다. Writing sample2.csv | index | c1 | c2 | c3 | |-------|----|----|-----| | 0 | 1 | 1.11 | one | | 1 | 2 | 2.22 | two | | 2 | 3 | 3.33 | three | 만약 테이블 내의 특정한 열을 행 인덱스로 저정하고 싶으면 인수를 사용한다. | c1 | c2 | c3 | |----|----|-----| | 1 | 1.11 | one | | 2 | 2.22 | two | | 3 | 3.33 | three | 확장자가 csv가 아닌 파일 즉, 데이터를 구분하는 구분자가 쉼표(Comma)가 아니면 인수를 써서 구분자를 지정해준다. 예를들면 구분자의 길이가 정해지지 않은 공백인 경우 정규식 문자열을 사용할 수 있다. Writing sample3.txt | index | c1 | c2 | c3 | c4 | |-------|------|--------|--------|--------| | 0 | 0.179181 | -1.538472 | 1.347553 | 0.43381 | | 1 | 1.024209 | 0.087307 | -1.281997 | 0.49265 | | 2 | 0.417899 | -2.002308 | 0.255245 | -1.10515 | 자료 파일중에 건너뛰어야 할 행이 있다면 인수를 사용한다. Writing sample4.txt | index | c1 | c2 | c3 | |-------|----|----|-----| | 0 | 1 | 1.11 | one | | 1 | 2 | 2.22 | two | | 2 | 3 | 3.33 | three | 특정한 값을 NaN으로 취급하고 싶으면 인수에 NaN값으로 취급할 값을 넣는다. Writing sample5.csv | index | c1 | c2 | c3 | |-------|----|----|-----| | 0 | 1.0 | 1.11 | one | | 1 | 2.0 | | two | | 2 | NaN | 3.33 | three | names : 열인덱스명이 없는경우 지정 가능 (,names=[['c1', 'c2', 'c3']]) sep : 데이터 구분자 지정 (,sep='\s+') skiprows : 행 건너뛰기 (,skiprows=[[0, 1]]) navalues : 특정값을 NaN값으로 대체 (,navalues=[['누락']]) CSV 파일 출력 ,c1, c2, c3 0,1.0, 1.11, one 1,2.0, , two 2,, 3.33, three 파일을 읽을때와 마찬가지로 출력할 때도 seq인수로 구분자를 바꿀 수 있다. 또 인수로 NaN 표시값을 바꿀 수도 있다. ,c1, c2, c3 0,1.0, 1.11, one 1,2.0, , two 2,누락, 3.33, three , 인수를 지정하여 인덱스 및 해더 출력 여부를 저정하는 것도 가능하다. | index | c1 | c2 | c3 | |-------|----|----|-----| | a | 1.0 | 1.11 | one | | b | 2.0 | | two | | c | NaN | 3.33 | three | 출처 : 데이터사이언스 스쿨(datascienceschool.net)
2020년 09월 27일6분Pandas 소개
PythonPandas 패키지 소개 Pandas 패키지는 데이터 분석을 할 때 가장 많이 쓰이는 패키지이다. 대부분의 데이터는 시계열(series)이나 표(table)의 형태로 나타낼 수 있는데 Pandas에서는 이러한 표 데이터를 다루기 위한 시리즈(Series) 클래스와 데이터프레임(DataFrame) 클래스를 제공한다. Series Series는 numpy에서 제공하는 1차원 배열과 비슷하지만 각 데이터의 의미를 표시하는 인덱스(index)를 붙일 수 있다. 데이터 자체는 값(Value)라고 한다. > Series = Value(값) + Index(인덱스) Series 생성 서울 9904312 부산 3448737 인천 2890451 대구 2466052 dtype: int64 만약 인덱스 지정 없이 Series를 만들면 Series의 인덱스는 0부터 시작하는 정수값이 된다. 0 10 1 11 2 12 3 13 dtype: int64 Index(['서울', '부산', '인천', '대구'], dtype='object') array([9904312, 3448737, 289511, 264544], dtype=int64) > - : Series 데이터의 이름 > - : Series 인덱스의 이름 도시 서울 9904312 부산 3448737 인천 289511 대구 264544 Name: 인구, dtype: int64 Series 연산 연산은 Series의 값에만 적용되며 인덱스 값은 변하지 않는다. 서울 9.904312 부산 3.448737 인천 2.890451 대구 2.466052 dtype: float64 Series 인덱싱 인덱스 라벨을 이용한 인덱싱 또는 배열 인덱싱을 이용한 슬라이싱이 가능하다. (3448737, 3448737) 배열 인덱싱을 하면 자료의 순서를 바꾸거나 특정 라벨의 자료만 선택할 수 있다. 서울 9904312 대구 2466052 dtype: int64 부산 3448737 인천 2890451 dtype: int64 서울 9904312 부산 3448737 인천 2890451 대구 2466052 dtype: int64 부산 3448737 인천 2890451 dtype: int64 만약 라벨 값이 영문인 경우에는 마치 속성처럼 점(.)을 이용하여 접근할 수도 있다. a 0 b 1 c 2 dtype: int64 (0, 1) Series와 Dictionary 자료형 Series 객체는 라벨 값에 의해 인덱싱이 가능하므로 실질적으로 라벨 값을 키(key)로 가지는 Dictionary 자료형과 같다고 볼수 있다. 따라서 Dictionary 자료형에서 제공하는 in 연산도 가능하고 items 메서드를 이용하면 for 루프를 통해 각 원소의 key와 value에 접근할 수도 있다. True False 서울 = 9904312 부산 = 3448737 인천 = 2890451 대구 = 2466052 또 Dictionary 객체에서 시리즈를 만들수 있다. 서울 9631482 부산 3393191 인천 2632035 대전 1490158 dtype: int64 Dictionary의 원소는 순서를 가지지 않으므로 Series의 데이터에도 순서가 보장되지 않는다. 만약 순서를 정하고 싶다면 인덱스를 리스트로 지정해야 한다. 부산 3393191 서울 9631482 인천 2632035 대전 1490158 dtype: int64 인덱스 기반 연산 s : 2015년 인구 증가 s2 : 2010년 인구 증가 대구 NaN 대전 NaN 부산 55546.0 서울 272830.0 인천 258416.0 dtype: float64 array([ 6511121, -6182745, 258416, 975894], dtype=int64) 대구와 대전의 경우 s, s1 모두에 준재하지 않기 때문에 계산이 불가능하므로 (Not a Number)값을 가지게 된다. 또한 값이 자료형에서만 가능하므로 다른 계산 결과도 모두 자료형이 되었다. 이 아닌 값을 구하려면 메서드를 사용하야 한다. 대구 False 대전 False 부산 True 서울 True 인천 True dtype: bool 부산 55546.0 서울 272830.0 인천 258416.0 dtype: float64 인구 증가율(%)은 다음과 같이 구할 수 있다. 부산 1.636984 서울 2.832690 인천 9.818107 dtype: float64 데이터 갱신, 추가, 삭제 인덱싱을 이용하면 딕셔너리처럼 데이터를 갱신하거나 추가 할 수 있다. 부산 1.630000 서울 2.832690 인천 9.818107 dtype: float64 부산 1.630000 서울 2.832690 인천 9.818107 대구 1.410000 dtype: float64 부산 1.630000 인천 9.818107 대구 1.410000 dtype: float64 DataFrame 시리즈가 1차원 벡터 데이터에 행방향 인덱스(row index)를 붙인 것이라면 데이터프레임 클래스는 2차원 행렬 데이터에 인덱스를 붙인 것과 비슷하다. 2차원이므로 각각의 행 데이터의 이름이 되는 행방향 인덱스(row index) 뿐 아니라 각각의 열 데이터의 이름이 되는 열방향 인덱스(column index)도 붙일 수 있다. DataFrame 생성 1. 하나의 열이 되는 데이터를 리스트나 일차원 배열로 준비 2. 이 각각의 열에 대한 이름(라벨)을 키로 가지는 딕셔너리 생성 3. 이 데이터를 DataFrame 클래스 생성자에 넣고 열방향 인덱스는 , 행방행 인덱스는 인수로 지정 | | 지역 | 2015 | 2010 | 2005 | 2000 | 2010-2015 증가율 | |-|-|-|-|-|-|-| | 서울 | 수도권 | 9904312 | 9631482 | 9762546 | 9853972 | 0.0283 | | 부산 | 경상권 | 3448737 | 3393191 | 3512547 | 3655437 | 0.0163 | | 인천 | 수도권 | 2890451 | 2632035 | 2517680 | 2466338 | 0.0982 | | 대구 | 경상권 | 2466052 | 2431774 | 2456016 | 2473990 | 0.0141 | 앞에서 데이터프레임은 2차원 배열 데이터를 기반으로 한다고 했지만 사실은 공통 인덱스를 가지는 열 시리즈(column series)를 딕셔너리로 묶어놓은 것이라고 보는것이 더 정확하다. 2차원 배열 데이터는 모든 원소와 같은 자료형을 가져야 하지만 데이터프레임은 각 열(column)마다 자료형이 다를 수 있기 때문이다. 위 예제에서도 지역과 인구와 증가율은 각각 문자열, 정수, 부동소수점 실수 이다. 시리즈와 마찬가지로 데이터만 접근하려면 속성을 사용하고, 열방향 인덱스와 행방향 인덱스는 각각 , 속성으로 접근한다. array([['수도권', 9904312, 9631482, 9762546, 9853972, 0.0283], ['경상권', 3448737, 3393191, 3512547, 3655437, 0.0163], ['수도권', 2890451, 2632035, 2517680, 2466338, 0.0982], ['경상권', 2466052, 2431774, 2456016, 2473990, 0.0141]], dtype=object) Index(['지역', '2015', '2010', '2005', '2000', '2010-2015 증가율'], dtype='object') Index(['서울', '부산', '인천', '대구'], dtype='object') 시리즈에서 처럼 열방향 인덱스와 행방향 인덱스에 이름을 붙일수 있다. | 특성\도시 | 지역 | 2015 | 2010 | 2005 | 2000 | 2010-2015 증가율 | |-|-|-|-|-|-|-| | 서울 | 수도권 | 9904312 | 9631482 | 9762546 | 9853972 | 0.0283 | | 부산 | 경상권 | 3448737 | 3393191 | 3512547 | 3655437 | 0.0163 | | 인천 | 수도권 | 2890451 | 2632035 | 2517680 | 2466338 | 0.0982 | | 대구 | 경상권 | 2466052 | 2431774 | 2456016 | 2473990 | 0.0141 | 데이터 프레임은 전치(transpose)를 포함하여 2차원 numpy 배열이 가지는 대부분의 속성이나 메서드를 지원한다. | 도시\특성 | 서울 | 부산 | 인천 | 대구 | |-|-|-|-|-| | 지역 | 수도권 | 경상권 | 수도권 | 경상권 | | 2015 | 9904312 | 3448737 | 2890451 | 2466052 | | 2010 | 9631482 | 3393191 | 2632035 | 2431774 | | 2005 | 9762546 | 3512547 | 2517680 | 2456016 | | 2000 | 9853972 | 3655437 | 2466338 | 2473990 | | 2010-2015 증가율 | 0.0283 | 0.0163 | 0.0982 | 0.0141 | 열 데이터의 갱신, 추가, 삭제 데이터프레임은 열 시리즈의 딕셔너리로 볼수 있으므로 열 단위로 데이터를 갱신하거나 추가, 삭제할 수 있다. | | 지역 | 2015 | 2010 | 2005 | 2000 | 2010-2015 증가율 | |-|-|-|-|-|-|-| | 서울 | 수도권 | 9904312 | 9631482 | 9762546 | 9853972 | 2.83 | | 부산 | 경상권 | 3448737 | 3393191 | 3512547 | 3655437 | 1.63 | | 인천 | 수도권 | 2890451 | 2632035 | 2517680 | 2466338 | 9.82 | | 대구 | 경상권 | 2466052 | 2431774 | 2456016 | 2473990 | 1.41 | | | 지역 | 2015 | 2010 | 2005 | 2000 | 2010-2015 증가율 | 2005-2010 등가율 | |-|-|-|-|-|-|-|-| | 서울 | 수도권 | 9904312 | 9631482 | 9762546 | 9853972 | 2.83 | -1.34 | | 부산 | 경상권 | 3448737 | 3393191 | 3512547 | 3655437 | 1.63 | -3.40 | | 인천 | 수도권 | 2890451 | 2632035 | 2517680 | 2466338 | 9.82 | 4.54 | | 대구 | 경상권 | 2466052 | 2431774 | 2456016 | 2473990 | 1.41 | -0.99 | | | 지역 | 2015 | 2010 | 2005 | 2000 | 2005-2010 등가율 | |-|-|-|-|-|-|-| | 서울 | 수도권 | 9904312 | 9631482 | 9762546 | 9853972 | -1.34 | | 부산 | 경상권 | 3448737 | 3393191 | 3512547 | 3655437 | -3.40 | | 인천 | 수도권 | 2890451 | 2632035 | 2517680 | 2466338 | 4.54 | | 대구 | 경상권 | 2466052 | 2431774 | 2456016 | 2473990 | -0.99 | 열 인덱싱 데이터프레임은 열 시리즈의 딕셔너리와 비슷하다고 하였다. 따라서 데이터프레임을 인덱싱 할 때도 열 라벨(column label)을 키값으로 생각하여 인덱싱을 할 수 있다. 인덱스로 라벨을 넣거나 배열형태로 넣는것도 가능하다. 서울 수도권 부산 경상권 인천 수도권 대구 경상권 Name: 지역, dtype: object pandas.core.series.Series | | 2010 | 2015 | |-|-|-| | 서울 | 9631482 | 9904312 | | 부산 | 3393191 | 3448737 | | 인천 | 2632035 | 2890451 | | 대구 | 2431774 | 2466052 | 만약 하나의 열만 빼서 데이터프레임 자료형을 유지하고 싶다면 원소가 하나인 리스트를 써서 인덱싱 하면된다. | | 2010 | |-|-| | 서울 | 9631482 | | 부산 | 3393191 | | 인천 | 2632035 | | 대구 | 2431774 | 서울 9631482 부산 3393191 인천 2632035 대구 2431774 Name: 2010, dtype: int64 데이터프레임의 열 인덱스가 문자열 라벨을 가지고 있는 경우에는 순서를 나타내는 정수 인덱스를 열 인덱싱에 사용할 수 없다. 다만 원래부터 문자열이 아닌 정수형 열 인덱스를 가지는 경우에는 인덱스 값으로 정수를 사용할 수 있다. | | 0 | 1 | 2 | 3 | |-|-|-|-|-| | 0 | 0 | 1 | 2 | 3 | | 1 | 4 | 5 | 6 | 7 | | 2 | 8 | 9 | 10 | 11 | 0 2 1 6 2 10 Name: 2, dtype: int32 | | 1 | 2 | |-|-|-| | 0 | 1 | 2 | | 1 | 5 | 6 | | 2 | 9 | 10 | 행 인덱싱 만약 행 단위로 인덱싱을 하고자 하면 항상 슬라이싱(slicing)을 해야 한다. 인덱스의 값이 문자 라벨이면 라벨 슬라이싱도 가능하다. | | 지역 | 2015 | 2010 | 2005 | 2000 | 2005-2010 등가율 | |-|-|-|-|-|-|-| | 서울 | 수도권 | 9904312 | 9631482 | 9762546 | 9853972 | -1.34 | | | 지역 | 2015 | 2010 | 2005 | 2000 | 2005-2010 등가율 | |-|-|-|-|-|-|-| | 부산 | 경상권 | 3448737 | 3393191 | 3512547 | 3655437 | -3.4 | | | 지역 | 2015 | 2010 | 2005 | 2000 | 2005-2010 등가율 | |-|-|-|-|-|-|-| | 서울 | 수도권 | 9904312 | 9631482 | 9762546 | 9853972 | -1.34 | | 부산 | 경상권 | 3448737 | 3393191 | 3512547 | 3655437 | -3.40 | 개별 데이터 인덱싱 데이터프레임에서 열 라벨로 시리즈를 인덱싱하면 시리즈가 된다. 이 시리즈를 다시 행 라벨로 인덱싱하면 개발 데이터가 나온다. 9904312 지금까지의 데이터프레임 인덱싱 방법을 정리하면 다음과 같다. | 인덱싱값 | 가능 | 결과 | 자료형 | 추가사항 | | :-------------------------- | :--: | :--: | :----------- | :----------------------------------------- | | 라벨 | O | 열 | 시리즈 | | | 라벨 리스트 | O | 열 | 데이터프레임 | | | 인덱스데이터(정수) | X | | | 열 라벨이 정수인 경우 라벨 인덱싱으로 인정 | | 인덱스데이터(정수 슬라이스) | O | 행 | 데이터프레임 | | 출처 : 데이터사이언스 스쿨(datascienceschool.net)
2020년 09월 26일17분