레이블이 pandas인 게시물을 표시합니다. 모든 게시물 표시
레이블이 pandas인 게시물을 표시합니다. 모든 게시물 표시

2021년 5월 16일 일요일

dataframe 열(column, 세로줄) 여러줄 multi-column 선택 in python

 

내용은 엄청 간단합니다. 그런데 말입니다. 막생 해보면 동시에 두개 열 선택이 잘 안됩니다.

자, 이제 예제 나갑니다.

>>> from pandas import Series, DataFrame
>>> raw_data = {'col0': [1, 2, 3, 4, 5],
...             'col1': [10, 20, 30, 40, 50],
...             'col2': [100, 200, 300, 400, 500]}
>>> data = DataFrame(raw_data)
>>> print(data)
   col0  col1  col2
0     1    10   100
1     2    20   200
2     3    30   300
3     4    40   400
4     5    50   500

간단하게 위와 같은 데이터를 만들었습니다.

즉 열 하나를 선택할때는 data['col1'] 이런식으로 하면됩니다.

>>> print(data['col1'])
0    10
1    20
2    30
3    40
4    50

잘 선택 되었습니다. 응용해보면, col1,col2를 선택하고 싶으면 data['col1','col2'] 넣으면 동작 하지 않습니다.

그러면 ?? 정답은 list로 묶어 주는것입니다.

>>> print(data[['col1','col2']])
   col1  col2
0    10   100
1    20   200
2    30   300
3    40   400
4    50   500

한개일때는 list로 안묶고, 두개이상일때는 list로 묶어주어야합니다. 

잘모를때는 한참 해메게 되는 tip이였습니다.


이쯤되면 궁금해지는데 한개일때도 리스트를 두번 사용하면 어떨까요? 이런 질문을 가지고 계신 분들을 위해서 시험해봤습니다. 정상 동작합니다.

>>> print(data[['col1']])
   col1
0    10
1    20
2    30
3    40
4    50


2020년 10월 25일 일요일

python pandas dataframe swapaxes example 축변환 예제

dataframe에서 축변환 하기 방법 

swapaxes 함수 사용 예제


예제를 위한 dataframe을 만듭니다.
Series로 dict형태로 묶어서 dataframe 인자로 넘깁니다. 일반적인 예제입니다.

예제 코드

import pandas as pd
import numpy as np

d = {'one' : pd.Series([1., 7., 3.]),
	'two' : pd.Series([1., 2., 3., 4.]),
	'3' : pd.Series([2., np.nan, 3., 4.])}
df = pd.DataFrame(d)

print(df)

실행 결과

   one  two    3
0  1.0  1.0  2.0
1  7.0  2.0  NaN
2  3.0  3.0  3.0
3  NaN  4.0  4.0


축변환 코드


축변환 후

import pandas as pd
import numpy as np

d = {'one' : pd.Series([1., 7., 3.]),
	'two' : pd.Series([1., 2., 3., 4.]),
	'3' : pd.Series([2., np.nan, 3., 4.])}
df = pd.DataFrame(d)

print(df.swapaxes("index","columns"))

축변환 결과

       0    1    2    3
one  1.0  7.0  3.0  NaN
two  1.0  2.0  3.0  4.0
3    2.0  NaN  3.0  4.0


축변환 하기전 index와 columns의 의미

swapaxes("index","columns") : 인자로 index와 columns 를 넘김 이것은 가로 세로의 전체 축을 대표하는 이름임 즉 가로 세로 전체축을 변환 하겠다는 의미입니다.

print(df.index)
print(df.columns)

RangeIndex(start=0, stop=4, step=1)
Index(['one', 'two', '3'], dtype='object')

index는 rangeindex type이고, column은 string list 형태의 값을 가지고 있음




2019년 2월 24일 일요일

시계열 데이터에서 Pandas를 이용한 lag data 생성


서론

머신러닝에서 입력되는 데이터는 간혹 시계열 데이터가 있습니다. 단순한 데이터의 예로는 주식값이 있습니다. 머신러닝에서는 이전 데이터를 현재 데이터에 넣으면 좀 더 정확한 학습이 가능한 경우가 있습니다. 이것을 lag(지연) 데이터라고 표현합니다.

방법

python에서는 lag 데이터 처리를 어떻게 하면 될까요? 현재 날짜 기준으로 이전 날짜 데이터가 빠지는 경우도 있습니다. 아래 데이터 참고 바랍니다.

lagdata.csv
date,K122630_close,K122630_open,K122630_high,K122630_low
2018-12-28,11445.0,11375.0,11530.0,11370.0
2018-12-27,11340.0,11405.0,11430.0,11280.0
2018-12-26,11030.0,11065.0,11200.0,10915.0
2018-12-24,11360.0,11310.0,11370.0,11225.0
2018-12-21,11370.0,11330.0,11405.0,11275.0
2018-12-20,11375.0,11485.0,11525.0,11260.0
2018-12-19,11625.0,11510.0,11640.0,11470.0
2018-12-18,11465.0,11365.0,11585.0,11365.0
2018-12-17,11555.0,11480.0,11625.0,11480.0

그래서 생각해볼 수 있는 방법이 pandas의 shift 함수 입니다.
http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.shift.html

여기에서는 shift 함수를 이용하여 lag 데이터를 만들 예정입니다.
구현 내용은 아래와 같습니다.

import pandas as pd
df = pd.read_csv('lagdata.csv', header=0, delimiter=',', encoding='utf8')
print(df)

df['K122630_close_lag'] = df['K122630_close'].shift(1)
print(df)
핵심은 아래와 같은 코드입니다. 새로운 K122630_close_lag 컬럼을 만들어 shift(1) 된 데이터를 넣어 주는것입니다.
df['K122630_close_lag'] = df['K122630_close'].shift(1)

결과
         date  K122630_close  K122630_open  K122630_high  K122630_low  K122630_close_lag
0  2018-12-28        11445.0       11375.0       11530.0      11370.0                NaN
1  2018-12-27        11340.0       11405.0       11430.0      11280.0            11445.0
2  2018-12-26        11030.0       11065.0       11200.0      10915.0            11340.0
3  2018-12-24        11360.0       11310.0       11370.0      11225.0            11030.0
4  2018-12-21        11370.0       11330.0       11405.0      11275.0            11360.0
5  2018-12-20        11375.0       11485.0       11525.0      11260.0            11370.0
6  2018-12-19        11625.0       11510.0       11640.0      11470.0            11375.0
7  2018-12-18        11465.0       11365.0       11585.0      11365.0            11625.0
8  2018-12-17        11555.0       11480.0       11625.0      11480.0            11465.0

실행한 결과는 위와 같습니다.
여기에서 생각해봐야 할것이 있습니다. lag 데이터는 현재 데이터에 과거 데이터를 올려서 feature를 만드는 것입니다. 그런데 12-28일 데이터를 보면 K122630_close_lag 값이 NaN 입니다. 그 말은 과거라면 데이터가 있어야 하지만 없다는 말입니다. shift가 뒤쪽으로 밀기 때문에 shift 값이 -1이 되어야 합니다. 또는 날짜의 sort를 바꿔야 합니다.

shift 값을 -1을 넣었습니다.
import pandas as pd
df = pd.read_csv('lagdata.csv', header=0, delimiter=',', encoding='utf8')
print(df)

df['K122630_close_lag'] = df['K122630_close'].shift(-1)
print(df)

shift 값을 -1의 결과 입니다.
         date  K122630_close  K122630_open  K122630_high  K122630_low  K122630_close_lag
0  2018-12-28        11445.0       11375.0       11530.0      11370.0            11340.0
1  2018-12-27        11340.0       11405.0       11430.0      11280.0            11030.0
2  2018-12-26        11030.0       11065.0       11200.0      10915.0            11360.0
3  2018-12-24        11360.0       11310.0       11370.0      11225.0            11370.0
4  2018-12-21        11370.0       11330.0       11405.0      11275.0            11375.0
5  2018-12-20        11375.0       11485.0       11525.0      11260.0            11625.0
6  2018-12-19        11625.0       11510.0       11640.0      11470.0            11465.0
7  2018-12-18        11465.0       11365.0       11585.0      11365.0            11555.0
8  2018-12-17        11555.0       11480.0       11625.0      11480.0                NaN

더 많은 lag들

이전 데이터가 하나만 필요한것은 아닙니다. 많은 lag가 더 높은 성능을 발휘 할때가 있습니다.
lag1, lag2를 추가하였습니다.
import pandas as pd
df = pd.read_csv('lagdata.csv', header=0, delimiter=',', encoding='utf8')
df['K122630_close_lag1'] = df['K122630_close'].shift(-1)
df['K122630_close_lag2'] = df['K122630_close'].shift(-2)
print(df)

결과는 아래와 같습니다.
         date  K122630_close  K122630_open         ...          K122630_low  K122630_close_lag1  K122630_close_lag2
0  2018-12-28        11445.0       11375.0         ...              11370.0             11340.0             11030.0
1  2018-12-27        11340.0       11405.0         ...              11280.0             11030.0             11360.0
2  2018-12-26        11030.0       11065.0         ...              10915.0             11360.0             11370.0
3  2018-12-24        11360.0       11310.0         ...              11225.0             11370.0             11375.0
4  2018-12-21        11370.0       11330.0         ...              11275.0             11375.0             11625.0
5  2018-12-20        11375.0       11485.0         ...              11260.0             11625.0             11465.0
6  2018-12-19        11625.0       11510.0         ...              11470.0             11465.0             11555.0
7  2018-12-18        11465.0       11365.0         ...              11365.0             11555.0                 NaN
8  2018-12-17        11555.0       11480.0         ...              11480.0                 NaN                 NaN




2019년 2월 19일 화요일

Python 에서 sqlite3 와 DataFrame 사용



Python을 이용한 sqlite3 사용 예제입니다. sqlite는 python을 설치하면 기본으로 설치되어있으며, db를 파일 형태로 저장하기 때문에 backup이나 관리가 쉬운 편입니다. 하지만 속도나 대용량 지원등 여러가지 제약 사항은 있습니다.
구현 하고자 하는 내용은 저장은 sqlite3로 하고 읽는 부분은 pandas dataframe을 이용하였습니다.
아래와 같이 테이블을 만들고 body 부분에 text를 넣는 예제입니다.

예제에서 입력을 원하는 db table 구조
table : maintbl

      date :  body
-----------+------
2019-02-18 : hello
2019-02-19 : nice

응용 해볼 수 있는 곳은 웹에서 자료를 읽어서 db에 읽어서 날짜별로 저장하고 읽을때는 DataFrame 사용하기 위한 용도입니다.

좀 더 단순화 위해서 database class를 제작하였습니다. 기본 idx 가 기본키로 지정되어 있습니다. pandas로 data를 읽는 부분은 다음 코드를 이용합니다. df = pd.read_sql_query("SELECT * FROM %s" % table, self.con)

database.py
import os
import sqlite3
import datetime
import pandas as pd
from pandas import Series, DataFrame

#print(str(sqlite3.version))

class SqliteDb():
    def __init__(self):
        super().__init__()

    def connect(self, name):
        self.con = sqlite3.connect(name)
        self.cursor = self.con.cursor()
        return self.cursor

    def make_table(self, table ):
        self.cursor.execute("CREATE TABLE "+ table + "(idx INTEGER PRIMARY KEY)")

    def exists_table(self, table):
        try :
            self.cursor.execute("SELECT * FROM " + table)
            return True
        except :
            return False

    def exists_table_column(self, table, coulumn) :
        try :
            self.cursor.execute("SELECT %s FROM %s "%(coulumn, table))
            return True
        except :
            return False

    def add_column(self, table, column_name_type) :
        # add column https://www.sqlite.org/datatype3.html
        # add_column(TABLE_NAME,'column_name float')
        sql = "ALTER TABLE %s ADD COLUMN %s" % (table, column_name_type)
        self.cursor.execute(sql)

    def insert_data(self, table, values):
        # column 순서 대로 입력됨
        #insert_data(TABLE_NAME,"'2018-01-01',1000")
        sql = "INSERT INTO %s VALUES(%s)" % (table, values)
        self.cursor.execute(sql)

    def insert_data_with_cols(self, table, cols, values):
        # 원하는 column 에 원하는 값을 넣을때 사용
        #insert_data_with_cols("table_name","column_name1,column_name2","value1,value2")
        sql = "INSERT INTO %s(%s) VALUES(%s)" % (table, cols, values)
        self.cursor.execute(sql)

    def get_value(self, table, cols, condition):
        #value = get_value("table_name","colname","idx=value")
        sql = "SELECT %s FROM %s WHERE %s" % (cols, table, condition)
        cursor = self.cursor.execute(sql)
        row = cursor.fetchone()
        if row==None : return None
        if len(row)==0 : return None
        return row[0]
    
    def update_value(self, table, setvalue, condition):
        #update_value("table_name","colname=value","idx=value")
        sql = "UPDATE %s SET %s WHERE %s" % (table, setvalue, condition)
        self.cursor.execute(sql)

    def get_dataframe(self, table):
        df = pd.read_sql_query("SELECT * FROM %s" % table, self.con)
        return df

    def close(self):
        self.con.commit()
        self.con.close()

컬럼을 추가할때 (db.add_column(PARAM_DB_TABLE_MAIN,"body TEXT")) db의 datatype은 https://www.sqlite.org/datatype3.html 링크를 참고합니다.
maintbl을 생성하는 예제 코드
import database

PARAM_DB_NAME = "dbname.db"
PARAM_DB_TABLE_MAIN = "maintbl"

db = database.SqliteDb()
db.connect(PARAM_DB_NAME)

# Table
if not db.exists_table(PARAM_DB_TABLE_MAIN):
 db.make_table(PARAM_DB_TABLE_MAIN)

# Columns
if not db.exists_table_column(PARAM_DB_TABLE_MAIN,"date"):
 db.add_column(PARAM_DB_TABLE_MAIN,"date TEXT")

if not db.exists_table_column(PARAM_DB_TABLE_MAIN,"body"):
 db.add_column(PARAM_DB_TABLE_MAIN,"body TEXT")

# insert update
idxvalue = db.get_value(PARAM_DB_TABLE_MAIN, "idx", "date='2019-02-18'")
if idxvalue==None:
 db.insert_data_with_cols(PARAM_DB_TABLE_MAIN,"date","'2019-02-18'")
 db.insert_data_with_cols(PARAM_DB_TABLE_MAIN,"body","'hello'")
else:
 db.update_value(PARAM_DB_TABLE_MAIN,"body='hello'","idx=%d"%idxvalue)

# insert update
idxvalue = db.get_value(PARAM_DB_TABLE_MAIN, "idx", "date='2019-02-19'")
if idxvalue==None:
 db.insert_data_with_cols(PARAM_DB_TABLE_MAIN,"date","'2019-02-19'")
 db.insert_data_with_cols(PARAM_DB_TABLE_MAIN,"body","'nice'")
else:
 db.update_value(PARAM_DB_TABLE_MAIN,"body='nice'","idx=%d"%idxvalue)

db.close()

db2 = database.SqliteDb()
db2.connect(PARAM_DB_NAME)
df = db2.get_dataframe(PARAM_DB_TABLE_MAIN)
print(df)

db에서 insert data를 할때 주의할점
insert data를 하면 row가 하나 증가됩니다.
즉, 위 실행 예제로 하면 아래와 같이 나옵니다.

실행예제1)
   idx        date   body
0    1  2019-02-18   None
1    2        None  hello
2    3  2019-02-19   None
3    4        None   nice

다시 동작시키면 아래와 같이 날짜 뒤 body 컬럼이 채워집니다.

실행예제2)
   idx        date   body
0    1  2019-02-18  hello
1    2        None  hello
2    3  2019-02-19   nice
3    4        None   nice

원했던 내용이 아닙니다.
insert를 하게되면 row가 하나 생겨나기 때문에 idx를 얻어서 나머지 컬럼은 update를 하는 방식을 사용하였습니다. 아래 부분이 변경되었습니다.
idxvalue = db.get_value(PARAM_DB_TABLE_MAIN, "idx", "date='2019-02-18'")
if idxvalue==None:
db.insert_data_with_cols(PARAM_DB_TABLE_MAIN,"date","'2019-02-18'")
idxvalue = db.get_value(PARAM_DB_TABLE_MAIN, "idx", "date='2019-02-18'")

db.update_value(PARAM_DB_TABLE_MAIN,"body='hello'","idx=%d"%idxvalue)


변경된 소스
import database

PARAM_DB_NAME = "dbname.db"
PARAM_DB_TABLE_MAIN = "maintbl"

db = database.SqliteDb()
db.connect(PARAM_DB_NAME)

# Table
if not db.exists_table(PARAM_DB_TABLE_MAIN):
 db.make_table(PARAM_DB_TABLE_MAIN)

# Columns
if not db.exists_table_column(PARAM_DB_TABLE_MAIN,"date"):
 db.add_column(PARAM_DB_TABLE_MAIN,"date TEXT")

if not db.exists_table_column(PARAM_DB_TABLE_MAIN,"body"):
 db.add_column(PARAM_DB_TABLE_MAIN,"body TEXT")

# insert update
idxvalue = db.get_value(PARAM_DB_TABLE_MAIN, "idx", "date='2019-02-18'")
if idxvalue==None:
 db.insert_data_with_cols(PARAM_DB_TABLE_MAIN,"date","'2019-02-18'")
 idxvalue = db.get_value(PARAM_DB_TABLE_MAIN, "idx", "date='2019-02-18'")

db.update_value(PARAM_DB_TABLE_MAIN,"body='hello'","idx=%d"%idxvalue)

# insert update
idxvalue = db.get_value(PARAM_DB_TABLE_MAIN, "idx", "date='2019-02-19'")
if idxvalue==None:
 db.insert_data_with_cols(PARAM_DB_TABLE_MAIN,"date","'2019-02-19'")
 idxvalue = db.get_value(PARAM_DB_TABLE_MAIN, "idx", "date='2019-02-19'")

db.update_value(PARAM_DB_TABLE_MAIN,"body='nice'","idx=%d"%idxvalue)

db.close()

db2 = database.SqliteDb()
db2.connect(PARAM_DB_NAME)
df = db2.get_dataframe(PARAM_DB_TABLE_MAIN)
print(df)

최종 실행결과
   idx        date   body
0    1  2019-02-18  hello
1    2  2019-02-19   nice


주의 : clean 테스트를 위해서는 현재 폴더에 있는 dbname.db 삭제해야합니다.


2019년 1월 13일 일요일

Machine Learning 에서 NaN 처리

Machine Learning 에서 NaN 처리

굉장히 고민이 되는 주제입니다.

https://stats.stackexchange.com/questions/258610/machine-learning-dealing-with-nan-values

위 답변의 결론은 NaN 값이 생성 하게 되는 방법을 (해당 항목이 왜 NaN이 된것인지)이해하고 각 기능의 예상되는 동작이 무엇인지 가정해서 진행해야 합니다. 어떤때는 0으로 치환되기도 하지만 어떤 경우에는 다른값 의미가 되어야 합니다. 그것은 해당 항목에 따라 면밀히 살펴보고 진행하여야 합니다.

어떤 값으로 변경해야 할지 모르기 때문에 다른 값으로 변경하는 예제를 만들어 두었습니다.

1. NaN 값을 -999 값으로 변경하기 pytorch tensor

import pandas as pd

dataset = pd.read_csv("train.tsv", delimiter='\t', header=0)
print(dataset.info(verbose=True))

import torch
one_hot_encoded = pd.get_dummies(dataset) 
torch_tensor = torch.from_numpy(one_hot_encoded.values)
print(torch_tensor)

torch_tensor[torch_tensor != torch_tensor] = -999
print(torch_tensor)

NaN텐서의 값을 변경하는 코드
torch_tensor[torch_tensor != torch_tensor] = -999

입력 데이터
0 1 지역 3 4
NaN 0.3160718715457761 광주 0.618074061962662 부산
0.4779143261004096 0.7640950473377978 인천 0.7554662967547567 인천
0.46356805076582885 0.5837447431729355 대전 0.793675978965779 광주
0.5695109222857196 0.05089301078346342 인천 0.9556152127770076 부산
0.04493729261707624 0.14316706161067427 경기 0.3853064558624778 울산
0.4211392967613088 0.4223696769241083 울산 0.5668579921124862 광주
0.6968309725237914 0.9771633054896907 서울 0.8357267917293922 경기
0.11353740126056755 0.7601654905557846 대전 0.743158407293178 부산
0.22370034270270966 0.3115915771469119 대전 0.11848968372403645 부산
0.137646137601257 0.600286886461799 광주 0.7007352606121582 강원
0.031428666050948184 0.39108944068098905 대전 0.8733145643417124 강원
0.9964849451141898 0.1515641318053479 인천 0.5335673749065628 인천
0.22542471556473298 0.8561772376533481 서울 0.9362096685200896 울산
0.4686621433360696 0.17537990374522128 대구 0.3499523151304561 울산
0.046060811241397714 0.8299155100569963 경기 0.21535901604117658 경기
0.1899909553960777 0.21936448957471155 인천 0.6575452140509177 경기
0.41758513381425333 0.42277109702047366 서울 0.8529515809615816 부산
0.3197992908993763 NaN 강원 0.4037015504523124 대구
0.0562629654450455 0.551939153390536 인천 0.9260164254116474 세종
0.587953265713976 0.6413981811587487 대구 0.023584307830762707 대전

결과
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20 entries, 0 to 19
Data columns (total 5 columns):
0     19 non-null float64
1     19 non-null float64
지역    20 non-null object
3     20 non-null float64
4     20 non-null object
dtypes: float64(3), object(2)
memory usage: 880.0+ bytes
None
tensor([[    nan,  0.3161,  0.6181,  0.0000,  0.0000,  1.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000],
        [ 0.4779,  0.7641,  0.7555,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  1.0000],
        [ 0.4636,  0.5837,  0.7937,  0.0000,  0.0000,  0.0000,  0.0000,
          1.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  1.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
        [ 0.5695,  0.0509,  0.9556,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000],
        [ 0.0449,  0.1432,  0.3853,  0.0000,  1.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  1.0000,  0.0000],
        [ 0.4211,  0.4224,  0.5669,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000,  1.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
        [ 0.6968,  0.9772,  0.8357,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  1.0000,  0.0000,  0.0000,  0.0000,  1.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
        [ 0.1135,  0.7602,  0.7432,  0.0000,  0.0000,  0.0000,  0.0000,
          1.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000],
        [ 0.2237,  0.3116,  0.1185,  0.0000,  0.0000,  0.0000,  0.0000,
          1.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000],
        [ 0.1376,  0.6003,  0.7007,  0.0000,  0.0000,  1.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  1.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
        [ 0.0314,  0.3911,  0.8733,  0.0000,  0.0000,  0.0000,  0.0000,
          1.0000,  0.0000,  0.0000,  0.0000,  1.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
        [ 0.9965,  0.1516,  0.5336,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  1.0000],
        [ 0.2254,  0.8562,  0.9362,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  1.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  1.0000,  0.0000],
        [ 0.4687,  0.1754,  0.3500,  0.0000,  0.0000,  0.0000,  1.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  1.0000,  0.0000],
        [ 0.0461,  0.8299,  0.2154,  0.0000,  1.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  1.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
        [ 0.1900,  0.2194,  0.6575,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  1.0000,  0.0000,  1.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
        [ 0.4176,  0.4228,  0.8530,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  1.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000],
        [ 0.3198,     nan,  0.4037,  1.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
          1.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
        [ 0.0563,  0.5519,  0.9260,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  1.0000,  0.0000,  0.0000],
        [ 0.5880,  0.6414,  0.0236,  0.0000,  0.0000,  0.0000,  1.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  1.0000,  0.0000,  0.0000,  0.0000,  0.0000]], dtype=torch.float64)
tensor([[-999.0000,    0.3161,    0.6181,    0.0000,    0.0000,    1.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000],
        [   0.4779,    0.7641,    0.7555,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    1.0000],
        [   0.4636,    0.5837,    0.7937,    0.0000,    0.0000,    0.0000,
            0.0000,    1.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    1.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000],
        [   0.5695,    0.0509,    0.9556,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000],
        [   0.0449,    0.1432,    0.3853,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            1.0000,    0.0000],
        [   0.4211,    0.4224,    0.5669,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    1.0000,    0.0000,    0.0000,
            0.0000,    1.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000],
        [   0.6968,    0.9772,    0.8357,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    1.0000,    0.0000,    0.0000,    0.0000,
            1.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000],
        [   0.1135,    0.7602,    0.7432,    0.0000,    0.0000,    0.0000,
            0.0000,    1.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000],
        [   0.2237,    0.3116,    0.1185,    0.0000,    0.0000,    0.0000,
            0.0000,    1.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000],
        [   0.1376,    0.6003,    0.7007,    0.0000,    0.0000,    1.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    1.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000],
        [   0.0314,    0.3911,    0.8733,    0.0000,    0.0000,    0.0000,
            0.0000,    1.0000,    0.0000,    0.0000,    0.0000,    1.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000],
        [   0.9965,    0.1516,    0.5336,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    1.0000],
        [   0.2254,    0.8562,    0.9362,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    1.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            1.0000,    0.0000],
        [   0.4687,    0.1754,    0.3500,    0.0000,    0.0000,    0.0000,
            1.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            1.0000,    0.0000],
        [   0.0461,    0.8299,    0.2154,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            1.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000],
        [   0.1900,    0.2194,    0.6575,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            1.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000],
        [   0.4176,    0.4228,    0.8530,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    1.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000],
        [   0.3198, -999.0000,    0.4037,    1.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    1.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000],
        [   0.0563,    0.5519,    0.9260,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    1.0000,
            0.0000,    0.0000],
        [   0.5880,    0.6414,    0.0236,    0.0000,    0.0000,    0.0000,
            1.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    1.0000,    0.0000,    0.0000,
            0.0000,    0.0000]], dtype=torch.float64)

참고로 NaN 인식하는 스트링 값은 nan,NaN,NA 3가지 이며 text에 해당 string이 있을때 숫자로 인식(numpy.nan)하게 됩니다.

2. pandas fillna 이용

>>> df = pd.DataFrame([[np.nan, 2, np.nan, 0],
...                    [3, 4, np.nan, 1],
...                    [np.nan, np.nan, np.nan, 5],
...                    [np.nan, 3, np.nan, 4]],
...                    columns=list('ABCD'))
>>> df
     A    B   C  D
0  NaN  2.0 NaN  0
1  3.0  4.0 NaN  1
2  NaN  NaN NaN  5
3  NaN  3.0 NaN  4
>>> df.fillna(0)
    A   B   C   D
0   0.0 2.0 0.0 0
1   3.0 4.0 0.0 1
2   0.0 0.0 0.0 5
3   0.0 3.0 0.0 4

3. 범주형 데이터 NaN 처리 방법

범주형이란 선택 사항이 유한한 집합에 속한 하나 이상의 이산 항목을 표현하는 입력 특성을 가리킵니다, 범주형 데이터에는 논리적 순서가 없을 수도 있습니다. 예를 들면, 범주형에는 성별, 지역, 결제 방법이 있습니다. 서울=1, 광주=2, 인천=3 으로 표현되더라도 해당 항목은 범주형에 해당됩니다. 인천(3)-광주(2)=서울(1)의 의미를 지니지 않기 때문입니다. 그러면 이러한 범주형 데이터는 Machine Learning에서 어떻게 해야할까요?
아래 좋은 자료가 있습니다.
https://blog.myyellowroad.com/using-categorical-data-in-machine-learning-with-python-from-dummy-variables-to-deep-category-66041f734512
https://blog.myyellowroad.com/using-categorical-data-in-machine-learning-with-python-from-dummy-variables-to-deep-category-42fd0a43b009

카테고리 데이터가 많지 않다면 one hot encoding 을 사용하는 방법입니다. 즉 인천에 차원 하나를 할당하고 서울에도 차원 하나를 할당 하는 방식입니다. pandas에 get_dummies 함수를 이용하면 쉽게 변환이 가능합니다.

입력 데이터
0 1 지역 3 4
NaN 0.3160718715457761 광주 0.618074061962662 부산
0.4779143261004096 0.7640950473377978 인천 0.7554662967547567 인천
0.46356805076582885 0.5837447431729355 대전 0.793675978965779 광주
0.5695109222857196 0.05089301078346342 인천 0.9556152127770076 부산
0.04493729261707624 0.14316706161067427 경기 0.3853064558624778 울산
0.4211392967613088 0.4223696769241083 울산 0.5668579921124862 광주
0.6968309725237914 0.9771633054896907 서울 0.8357267917293922 경기
0.11353740126056755 0.7601654905557846 대전 0.743158407293178 부산
0.22370034270270966 0.3115915771469119 대전 0.11848968372403645 부산
0.137646137601257 0.600286886461799 광주 0.7007352606121582 강원
0.031428666050948184 0.39108944068098905 대전 0.8733145643417124 강원
0.9964849451141898 0.1515641318053479 인천 0.5335673749065628 인천
0.22542471556473298 0.8561772376533481 서울 0.9362096685200896 울산
0.4686621433360696 0.17537990374522128 대구 0.3499523151304561 울산
0.046060811241397714 0.8299155100569963 경기 0.21535901604117658 경기
0.1899909553960777 0.21936448957471155 인천 0.6575452140509177 NaN
0.41758513381425333 0.42277109702047366 서울 0.8529515809615816 부산
0.3197992908993763 NaN 강원 0.4037015504523124 대구
0.0562629654450455 0.551939153390536 인천 0.9260164254116474 세종
0.587953265713976 0.6413981811587487 대구 0.023584307830762707 대전

코드에 dummy_na=True 옵션을 넣으면 다음 코드에 의해서  pd.get_dummies(dataset,dummy_na=True),  4_nan와 같이 마지막 항목에 nan 처리를 위한 차원이 늘어나게 됩니다.
import pandas as pd

dataset = pd.read_csv("train.tsv", delimiter='\t', header=0)
print(dataset.info(verbose=True))
print(dataset)

import torch
one_hot_encoded = pd.get_dummies(dataset,dummy_na=True) 
print(one_hot_encoded)
print(one_hot_encoded.info(verbose=True))

결과
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20 entries, 0 to 19
Data columns (total 5 columns):
0     19 non-null float64
1     19 non-null float64
지역    20 non-null object
3     20 non-null float64
4     19 non-null object
dtypes: float64(3), object(2)
memory usage: 880.0+ bytes
None
           0         1  지역         3    4
0        NaN  0.316072  광주  0.618074   부산
1   0.477914  0.764095  인천  0.755466   인천
2   0.463568  0.583745  대전  0.793676   광주
3   0.569511  0.050893  인천  0.955615   부산
4   0.044937  0.143167  경기  0.385306   울산
5   0.421139  0.422370  울산  0.566858   광주
6   0.696831  0.977163  서울  0.835727   경기
7   0.113537  0.760165  대전  0.743158   부산
8   0.223700  0.311592  대전  0.118490   부산
9   0.137646  0.600287  광주  0.700735   강원
10  0.031429  0.391089  대전  0.873315   강원
11  0.996485  0.151564  인천  0.533567   인천
12  0.225425  0.856177  서울  0.936210   울산
13  0.468662  0.175380  대구  0.349952   울산
14  0.046061  0.829916  경기  0.215359   경기
15  0.189991  0.219364  인천  0.657545  NaN
16  0.417585  0.422771  서울  0.852952   부산
17  0.319799       NaN  강원  0.403702   대구
18  0.056263  0.551939  인천  0.926016   세종
19  0.587953  0.641398  대구  0.023584   대전
           0         1         3  지역_강원  지역_경기  지역_광주  지역_대구  지역_대전  지역_서울  지역_울산  ...    4_강원  4_경기  4_광주  4_대구  4_대전  4_부산  4_세종  4_울산  4_인천  4_nan
0        NaN  0.316072  0.618074      0      0      1      0      0      0      0  ...       0     0     0     0     0     1     0     0     0      0
1   0.477914  0.764095  0.755466      0      0      0      0      0      0      0  ...       0     0     0     0     0     0     0     0     1      0
2   0.463568  0.583745  0.793676      0      0      0      0      1      0      0  ...       0     0     1     0     0     0     0     0     0      0
3   0.569511  0.050893  0.955615      0      0      0      0      0      0      0  ...       0     0     0     0     0     1     0     0     0      0
4   0.044937  0.143167  0.385306      0      1      0      0      0      0      0  ...       0     0     0     0     0     0     0     1     0      0
5   0.421139  0.422370  0.566858      0      0      0      0      0      0      1  ...       0     0     1     0     0     0     0     0     0      0
6   0.696831  0.977163  0.835727      0      0      0      0      0      1      0  ...       0     1     0     0     0     0     0     0     0      0
7   0.113537  0.760165  0.743158      0      0      0      0      1      0      0  ...       0     0     0     0     0     1     0     0     0      0
8   0.223700  0.311592  0.118490      0      0      0      0      1      0      0  ...       0     0     0     0     0     1     0     0     0      0
9   0.137646  0.600287  0.700735      0      0      1      0      0      0      0  ...       1     0     0     0     0     0     0     0     0      0
10  0.031429  0.391089  0.873315      0      0      0      0      1      0      0  ...       1     0     0     0     0     0     0     0     0      0
11  0.996485  0.151564  0.533567      0      0      0      0      0      0      0  ...       0     0     0     0     0     0     0     0     1      0
12  0.225425  0.856177  0.936210      0      0      0      0      0      1      0  ...       0     0     0     0     0     0     0     1     0      0
13  0.468662  0.175380  0.349952      0      0      0      1      0      0      0  ...       0     0     0     0     0     0     0     1     0      0
14  0.046061  0.829916  0.215359      0      1      0      0      0      0      0  ...       0     1     0     0     0     0     0     0     0      0
15  0.189991  0.219364  0.657545      0      0      0      0      0      0      0  ...       0     0     0     0     0     0     0     0     0      1
16  0.417585  0.422771  0.852952      0      0      0      0      0      1      0  ...       0     0     0     0     0     1     0     0     0      0
17  0.319799       NaN  0.403702      1      0      0      0      0      0      0  ...       0     0     0     1     0     0     0     0     0      0
18  0.056263  0.551939  0.926016      0      0      0      0      0      0      0  ...       0     0     0     0     0     0     1     0     0      0
19  0.587953  0.641398  0.023584      0      0      0      1      0      0      0  ...       0     0     0     0     1     0     0     0     0      0

[20 rows x 22 columns]
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20 entries, 0 to 19
Data columns (total 22 columns):
0         19 non-null float64
1         19 non-null float64
3         20 non-null float64
지역_강원     20 non-null uint8
지역_경기     20 non-null uint8
지역_광주     20 non-null uint8
지역_대구     20 non-null uint8
지역_대전     20 non-null uint8
지역_서울     20 non-null uint8
지역_울산     20 non-null uint8
지역_인천     20 non-null uint8
지역_nan    20 non-null uint8
4_강원      20 non-null uint8
4_경기      20 non-null uint8
4_광주      20 non-null uint8
4_대구      20 non-null uint8
4_대전      20 non-null uint8
4_부산      20 non-null uint8
4_세종      20 non-null uint8
4_울산      20 non-null uint8
4_인천      20 non-null uint8
4_nan     20 non-null uint8
dtypes: float64(3), uint8(19)
memory usage: 940.0 bytes
None



2019년 1월 6일 일요일

구매 내역 특징 feature 추출(2) with pandas


1. 지난 이야기

https://swlock.blogspot.com/2018/12/feature.html

고민해서 만들어봤는데요. 실제 테스트해보니 속도가 너무 떨어집니다. 어디에 내놓고 쓸만한 내용은 아닌것 같아서 추가 분석해보았습니다.

2. 데이터 준비

일단 큰 데이터를 준비합니다. 20만건정도 되는 데이터를 준비하였습니다.
생성 코드
import numpy as np
import csv


MAX_ITEM = 200000
MAX_COLMUM = 4

title = 'Name Product Date Sellcount'.split()
name = 'micle sally pop kim park don'.split()
product = 'PA PB PC PD PE PF'.split()


f = open('train_long.csv', 'w', encoding='utf-8', newline='')
wr = csv.writer(f, delimiter=',')
wr.writerow(title)

for index in range(0,MAX_ITEM):
 random_data = np.random.rand(MAX_COLMUM).tolist()
 random_data[0] = name[int((random_data[0]*len(name))%len(name))]
 random_data[1] = product[int((random_data[1]*len(product))%len(product))]
 random_data[2] = int((random_data[2]*100)%100)
 random_data[3] = int((random_data[3]*5)%5)
 wr.writerow(random_data)
f.close()
코드 설명
4개의 컬럼을 가지고 (Name, Product, Date, Sellcount) 실제 데이터는 random_data[0],random_data[1],random_data[2],random_data[3] 이곳에 저장되며 wr.writerow(random_data)함수에 의해서 파일로 저장됩니다.

실행코드
import pandas as pd
import time

start = time.time()

df = pd.read_csv("train_long.csv", delimiter=',', header=0)
#print("## All")
#print(df)
 
#print("## Name")
df_name = df["Name"].drop_duplicates()
#print(df_name)
#print("## Product")
df_product = df["Product"].drop_duplicates()
#print(df_product)

PRIOD_COND=[(0,3),(4,6),(7,12),(13,24),(25,48),(49,96),(97,999)]
table_dict = {}

df_o = pd.DataFrame({})

for name in list(df_name):
 tlist = [name]
 for product in list(df_product):
  for condl,condh in PRIOD_COND:
   df_c = df.copy()
   df_c = df_c.loc[(df_c['Name'] == name)&(df_c['Product'] == product)&(df_c['Date'] >= condl)&(df_c['Date'] <= condh)]
   #print("## select ",name,product,condl,condh)
   #if(len(df_c.index)>0):
    #print(df_c)
    #print("sum",df_c["Sellcount"].sum())
   tlist.append(df_c["Sellcount"].sum())
 print(tlist)
 df_o = df_o.append( pd.DataFrame(tlist).T )
print ("## Result1")
print (df_o)

tlist = ["Name"]
for product in list(df_product):
 for condl,condh in PRIOD_COND:
  tlist.append(product+"_"+str(condh))
  
df_o.columns=(tlist)
print ("## Result2")
print (df_o)
print ("timediff :",time.time()-start,"sec")
코드 설명
위 코드는 이전에 작성하였던 코드에 마지막에 시간을 초단위로 나오도록 (time.time()-start)추가 하였습니다.

실행결과
['pop', 470, 353, 634, 1408, 2605, 5256, 296, 419, 297, 729, 1210, 2784, 5314, 360, 456, 336, 652, 1320, 2650, 5174, 379, 433, 315, 614, 1254, 2571, 5340, 315, 430, 312, 646, 1338, 2582, 5305, 374, 452, 379, 699, 1347, 2594, 5417, 319]
['kim', 441, 332, 745, 1272, 2617, 5440, 293, 468, 348, 743, 1261, 2711, 5417, 310, 466, 287, 631, 1335, 2579, 5238, 349, 464, 323, 626, 1225, 2620, 5426, 318, 441, 266, 678, 1279, 2727, 5484, 383, 473, 358, 677, 1320, 2653, 5247, 334]
['don', 469, 362, 668, 1259, 2725, 5206, 340, 380, 286, 694, 1276, 2833, 5439, 318, 394, 324, 613, 1342, 2687, 5278, 344, 483, 376, 727, 1254, 2889, 5296, 363, 465, 321, 609, 1443, 2532, 5208, 312, 469, 334, 666, 1446, 2834, 5488, 333]
['sally', 425, 315, 753, 1328, 2706, 5441, 357, 455, 315, 682, 1420, 2627, 5203, 257, 518, 289, 658, 1291, 2846, 5301, 354, 402, 327, 691, 1407, 2558, 5361, 374, 406, 354, 627, 1236, 2744, 5196, 309, 448, 303, 712, 1253, 2855, 5284, 338]
['micle', 440, 414, 739, 1312, 2559, 5462, 368, 459, 305, 631, 1270, 2713, 5460, 333, 367, 298, 708, 1284, 2863, 5283, 343, 447, 363, 758, 1365, 2555, 5257, 267, 477, 359, 677, 1222, 2679, 5612, 337, 475, 344, 662, 1246, 2677, 5170, 349]
['park', 445, 308, 651, 1290, 2598, 5258, 360, 517, 333, 680, 1227, 2751, 5290, 318, 418, 325, 668, 1402, 2719, 5398, 319, 415, 361, 676, 1365, 2624, 5335, 379, 459, 311, 623, 1287, 2729, 5467, 395, 448, 321, 695, 1327, 2561, 5186, 307]
## Result1
      0    1    2    3     4     5     6    7    8    9  ...     33    34   35   36   37   38    39    40    41   42
0    pop  470  353  634  1408  2605  5256  296  419  297 ...   2582  5305  374  452  379  699  1347  2594  5417  319
0    kim  441  332  745  1272  2617  5440  293  468  348 ...   2727  5484  383  473  358  677  1320  2653  5247  334
0    don  469  362  668  1259  2725  5206  340  380  286 ...   2532  5208  312  469  334  666  1446  2834  5488  333
0  sally  425  315  753  1328  2706  5441  357  455  315 ...   2744  5196  309  448  303  712  1253  2855  5284  338
0  micle  440  414  739  1312  2559  5462  368  459  305 ...   2679  5612  337  475  344  662  1246  2677  5170  349
0   park  445  308  651  1290  2598  5258  360  517  333 ...   2729  5467  395  448  321  695  1327  2561  5186  307

[6 rows x 43 columns]
## Result2
    Name PD_3 PD_6 PD_12 PD_24 PD_48 PD_96 PD_999 PA_3  ...   PC_96 PC_999 PF_3 PF_6 PF_12 PF_24 PF_48 PF_96 PF_999
0    pop  470  353   634  1408  2605  5256    296  419  ...    5305    374  452  379   699  1347  2594  5417    319
0    kim  441  332   745  1272  2617  5440    293  468  ...    5484    383  473  358   677  1320  2653  5247    334
0    don  469  362   668  1259  2725  5206    340  380  ...    5208    312  469  334   666  1446  2834  5488    333
0  sally  425  315   753  1328  2706  5441    357  455  ...    5196    309  448  303   712  1253  2855  5284    338
0  micle  440  414   739  1312  2559  5462    368  459  ...    5612    337  475  344   662  1246  2677  5170    349
0   park  445  308   651  1290  2598  5258    360  517  ...    5467    395  448  321   695  1327  2561  5186    307

[6 rows x 43 columns]
timediff : 21.010799407958984 sec

제 PC 환경에서 21초가 걸립니다. 더 큰 데이터가 존재한다면 무시할 수 없는 수치 입니다.
시간이 떨어지는 부분은 다음 구간입니다.
df_c = df_c.loc[(df_c['Name'] == name)&(df_c['Product'] == product)&(df_c['Date'] >= condl)&(df_c['Date'] <= condh)]
20만건이나 되는 data에서 원하는 row를 선택할때 속도가 많이 떨어지게 됩니다. 개선 방법은 df_c['Name'] == name 만 우선 선택하는 방법을 취할 것입니다.

3. 개선된 코드

import pandas as pd
import time

start = time.time()

df = pd.read_csv("train_long.csv", delimiter=',', header=0)
#print("## All")
#print(df)
 
#print("## Name")
df_name = df["Name"].drop_duplicates()
#print(df_name)
#print("## Product")
df_product = df["Product"].drop_duplicates()
#print(df_product)

PRIOD_COND=[(0,3),(4,6),(7,12),(13,24),(25,48),(49,96),(97,999)]
table_dict = {}

df_o = pd.DataFrame({})

for name in list(df_name):
 tlist = [name]
 df_cn = df.loc[(df['Name'] == name)]
 for product in list(df_product):
  for condl,condh in PRIOD_COND:
   df_cnr = df_cn.loc[(df_cn['Product'] == product)&(df_cn['Date'] >= condl)&(df_cn['Date'] <= condh)]
   tlist.append(df_cnr["Sellcount"].sum())
 print(tlist)
 df_o = df_o.append( pd.DataFrame(tlist).T )
print ("## Result1")
print (df_o)

tlist = ["Name"]
for product in list(df_product):
 for condl,condh in PRIOD_COND:
  tlist.append(product+"_"+str(condh))
  
df_o.columns=(tlist)
print ("## Result2")
print (df_o)
print ("timediff :",time.time()-start,"sec")

product for loop 밖에서 일부 데이터를 select하여 df_cn을 만듭니다.
 df_cn = df.loc[(df['Name'] == name)]
 for product in list(df_product):
그리고 루프안에서는 아래와 같이 Name이 빠진 코드로 검색을 하게 됩니다.
df_cnr = df_cn.loc[(df_cn['Product'] == product)&(df_cn['Date'] >= condl)&(df_cn['Date'] <= condh)]

결과
['pop', 470, 353, 634, 1408, 2605, 5256, 296, 419, 297, 729, 1210, 2784, 5314, 360, 456, 336, 652, 1320, 2650, 5174, 379, 433, 315, 614, 1254, 2571, 5340, 315, 430, 312, 646, 1338, 2582, 5305, 374, 452, 379, 699, 1347, 2594, 5417, 319]
['kim', 441, 332, 745, 1272, 2617, 5440, 293, 468, 348, 743, 1261, 2711, 5417, 310, 466, 287, 631, 1335, 2579, 5238, 349, 464, 323, 626, 1225, 2620, 5426, 318, 441, 266, 678, 1279, 2727, 5484, 383, 473, 358, 677, 1320, 2653, 5247, 334]
['don', 469, 362, 668, 1259, 2725, 5206, 340, 380, 286, 694, 1276, 2833, 5439, 318, 394, 324, 613, 1342, 2687, 5278, 344, 483, 376, 727, 1254, 2889, 5296, 363, 465, 321, 609, 1443, 2532, 5208, 312, 469, 334, 666, 1446, 2834, 5488, 333]
['sally', 425, 315, 753, 1328, 2706, 5441, 357, 455, 315, 682, 1420, 2627, 5203, 257, 518, 289, 658, 1291, 2846, 5301, 354, 402, 327, 691, 1407, 2558, 5361, 374, 406, 354, 627, 1236, 2744, 5196, 309, 448, 303, 712, 1253, 2855, 5284, 338]
['micle', 440, 414, 739, 1312, 2559, 5462, 368, 459, 305, 631, 1270, 2713, 5460, 333, 367, 298, 708, 1284, 2863, 5283, 343, 447, 363, 758, 1365, 2555, 5257, 267, 477, 359, 677, 1222, 2679, 5612, 337, 475, 344, 662, 1246, 2677, 5170, 349]
['park', 445, 308, 651, 1290, 2598, 5258, 360, 517, 333, 680, 1227, 2751, 5290, 318, 418, 325, 668, 1402, 2719, 5398, 319, 415, 361, 676, 1365, 2624, 5335, 379, 459, 311, 623, 1287, 2729, 5467, 395, 448, 321, 695, 1327, 2561, 5186, 307]
## Result1
      0    1    2    3     4     5     6    7    8    9  ...     33    34   35   36   37   38    39    40    41   42
0    pop  470  353  634  1408  2605  5256  296  419  297 ...   2582  5305  374  452  379  699  1347  2594  5417  319
0    kim  441  332  745  1272  2617  5440  293  468  348 ...   2727  5484  383  473  358  677  1320  2653  5247  334
0    don  469  362  668  1259  2725  5206  340  380  286 ...   2532  5208  312  469  334  666  1446  2834  5488  333
0  sally  425  315  753  1328  2706  5441  357  455  315 ...   2744  5196  309  448  303  712  1253  2855  5284  338
0  micle  440  414  739  1312  2559  5462  368  459  305 ...   2679  5612  337  475  344  662  1246  2677  5170  349
0   park  445  308  651  1290  2598  5258  360  517  333 ...   2729  5467  395  448  321  695  1327  2561  5186  307

[6 rows x 43 columns]
## Result2
    Name PD_3 PD_6 PD_12 PD_24 PD_48 PD_96 PD_999 PA_3  ...   PC_96 PC_999 PF_3 PF_6 PF_12 PF_24 PF_48 PF_96 PF_999
0    pop  470  353   634  1408  2605  5256    296  419  ...    5305    374  452  379   699  1347  2594  5417    319
0    kim  441  332   745  1272  2617  5440    293  468  ...    5484    383  473  358   677  1320  2653  5247    334
0    don  469  362   668  1259  2725  5206    340  380  ...    5208    312  469  334   666  1446  2834  5488    333
0  sally  425  315   753  1328  2706  5441    357  455  ...    5196    309  448  303   712  1253  2855  5284    338
0  micle  440  414   739  1312  2559  5462    368  459  ...    5612    337  475  344   662  1246  2677  5170    349
0   park  445  308   651  1290  2598  5258    360  517  ...    5467    395  448  321   695  1327  2561  5186    307

[6 rows x 43 columns]
timediff : 2.570505666732788 sec

21초->2.5초정도 걸렸습니다. 10배 정도 단축되었습니다.

4. 추가 개선된 코드

이번에는 groupby라는 기능을 이용할 것입니다. group로 묶는 기능인데 현재 Date 기준으로 날짜를 묶어야 하는것이 필요하기 때문에 cut 기능도 동시에 사용할 것입니다. 전체 코드를 보면서 이해를 하면 쉽습니다.

import pandas as pd
import time

start = time.time()

df = pd.read_csv("train_long.csv", delimiter=',', header=0)
#print("## All")
#print(df)
 
PRIOD_COND=[-1,3,6,12,24,48,96,999]
PRIOD_labels = ["3", "6", "12", "24", "48","96","999"]
table_dict = {}

cutdata = pd.cut(df["Date"], PRIOD_COND, labels=PRIOD_labels)
df["Cutdata"]=cutdata

print(df)

print(df.groupby([df["Name"],df["Product"],df["Cutdata"]]).sum()["Sellcount"])

print(df.groupby([df["Name"],df["Product"],df["Cutdata"]]).sum()["Sellcount"].unstack(["Product","Cutdata"]))

df_o = df.groupby([df["Name"],df["Product"],df["Cutdata"]]).sum()["Sellcount"].unstack(["Product","Cutdata"])

print(df_o)

print ("timediff :",time.time()-start,"sec")

Date가 숫자로만 되어있어서 그룹을 만들기가 어려웠습니다. 그래서 특정 수치일때 그것을 카테고리화 하는 함수를 필요로 합니다. 이것을 pd.cut이 도와주는데요. 여기에서는 아래 코드 부분입니다.
cutdata = pd.cut(df["Date"], PRIOD_COND, labels=PRIOD_labels)
대상은 df["Date"] 첫번째 인자의 cell이 되고, PRIOD_COND=[-1,3,6,12,24,48,96,999] 는 구간을 나눌때 경계가 되는 값입니다. 즉 -1~3, 4~6, 7~12 .... 이런식이 됩니다. 이때 label을 붙여줄 수 있는데 그 코드가  이런 코드 입니다. labels=PRIOD_labels
다시 설명하지면
PRIOD_COND=[-1,3,6,12,24,48,96,999]
PRIOD_labels = ["3", "6", "12", "24", "48","96","999"]
-1~3=>"3", 4~6=>"4" 가 되는 것입니다.
그 결과로 Cutdata cell에 값을 넣습니다.
df["Cutdata"]=cutdata
위코드에서 unstack 설명을 하려고 다음 코드를 준비하였습니다.
print(df.groupby([df["Name"],df["Product"],df["Cutdata"]]).sum()["Sellcount"])
print(df.groupby([df["Name"],df["Product"],df["Cutdata"]]).sum()["Sellcount"].unstack(["Product","Cutdata"]))
unstack전 코드는 아래와 같고
print(df.groupby([df["Name"],df["Product"],df["Cutdata"]]).sum()["Sellcount"])
결과를 살펴보면 아래와 같은 형태가 됩니다. 
Name   Product  Cutdata
don    PA       3           380
                6           286
                12          694
                24         1276
                48         2833
                96         5439
                999         318
       PB       3           483
                6           376
                12          727
                24         1254
                48         2889
                96         5296
                999         363
위 결과에 unstack으로 선택된 항목은 column으로 이동하게 됩니다. 즉 우리가 바라는 결과는 위 결과에서 Proudct와 Cutdata 날짜가 위쪽으로 가기를 원합니다. 그게 앞서 결과에 있었던 아래와 같은 형태를 취하게 됩니다.
Name PD_3 PD_6 PD_12 PD_24 PD_48 PD_96 PD_999
...생략... 

그래서 unstack(["Product","Cutdata"] 과 같은 코드가 필요하게 되고 결과는 아래와 같이 됩니다.
Product   PA                                    PB
Cutdata    3    6   12    24    48    96  999    3
Name                                             
don      380  286  694  1276  2833  5439  318  483
...생략... 

시간은 0.7초 정도 걸렸습니다. 결과는 아래 참고하기 바랍니다.

결과
         Name Product  Date  Sellcount Cutdata
0         pop      PD    68          3      96
1         kim      PA     1          2       3
2         don      PA    34          3      48
3       sally      PE    38          3      48
4       micle      PA    17          4      24
5         pop      PB    48          0      48
6        park      PB    35          0      48
7       sally      PC    69          4      96
8       sally      PD     8          0      12
9       sally      PE    71          1      96
10       park      PC    96          3      96
11      micle      PD    11          2      12
12        pop      PF     0          3       3
13        don      PB    49          4      96
14        don      PF    97          2     999
15       park      PF    21          0      24
16        kim      PD    37          0      48
17        pop      PC    72          2      96
18        don      PF    80          1      96
19        pop      PA    92          4      96
20        don      PF    88          2      96
21        don      PC    38          4      48
22        pop      PF    68          4      96
23      sally      PA    96          1      96
24       park      PA     0          2       3
25      micle      PD    50          4      96
26       park      PE    54          2      96
27      micle      PE     5          3       6
28        don      PF    89          1      96
29        kim      PF    32          3      48
...       ...     ...   ...        ...     ...
199970  sally      PA    53          0      96
199971   park      PA    27          1      48
199972  micle      PF    72          3      96
199973   park      PB    88          2      96
199974  micle      PC    25          3      48
199975    pop      PC    53          3      96
199976    pop      PE    36          3      48
199977  micle      PC    68          0      96
199978    don      PF    20          0      24
199979  sally      PA    21          2      24
199980  micle      PB    80          3      96
199981  sally      PF    37          0      48
199982  sally      PB    87          0      96
199983    pop      PC    36          0      48
199984    don      PA    24          4      24
199985    kim      PD    84          2      96
199986    kim      PA    51          2      96
199987    don      PA     6          4       6
199988    kim      PB    70          4      96
199989    pop      PE    68          1      96
199990  micle      PE    96          1      96
199991    pop      PE     7          4      12
199992  sally      PD    11          4      12
199993    kim      PD    15          1      24
199994  micle      PD    12          0      12
199995  micle      PD    67          1      96
199996   park      PC    57          2      96
199997    don      PF    62          3      96
199998    pop      PF    54          0      96
199999    pop      PF    40          1      48

[200000 rows x 5 columns]
Name   Product  Cutdata
don    PA       3           380
                6           286
                12          694
                24         1276
                48         2833
                96         5439
                999         318
       PB       3           483
                6           376
                12          727
                24         1254
                48         2889
                96         5296
                999         363
       PC       3           465
                6           321
                12          609
                24         1443
                48         2532
                96         5208
                999         312
       PD       3           469
                6           362
                12          668
                24         1259
                48         2725
                96         5206
                999         340
       PE       3           394
                6           324
                           ...
sally  PB       96         5361
                999         374
       PC       3           406
                6           354
                12          627
                24         1236
                48         2744
                96         5196
                999         309
       PD       3           425
                6           315
                12          753
                24         1328
                48         2706
                96         5441
                999         357
       PE       3           518
                6           289
                12          658
                24         1291
                48         2846
                96         5301
                999         354
       PF       3           448
                6           303
                12          712
                24         1253
                48         2855
                96         5284
                999         338
Name: Sellcount, Length: 252, dtype: int64
Product   PA                                    PB           ...     PE              PF                                 
Cutdata    3    6   12    24    48    96  999    3    6   12 ...     48    96  999    3    6   12    24    48    96  999
Name                                                         ...                                                        
don      380  286  694  1276  2833  5439  318  483  376  727 ...   2687  5278  344  469  334  666  1446  2834  5488  333
kim      468  348  743  1261  2711  5417  310  464  323  626 ...   2579  5238  349  473  358  677  1320  2653  5247  334
micle    459  305  631  1270  2713  5460  333  447  363  758 ...   2863  5283  343  475  344  662  1246  2677  5170  349
park     517  333  680  1227  2751  5290  318  415  361  676 ...   2719  5398  319  448  321  695  1327  2561  5186  307
pop      419  297  729  1210  2784  5314  360  433  315  614 ...   2650  5174  379  452  379  699  1347  2594  5417  319
sally    455  315  682  1420  2627  5203  257  402  327  691 ...   2846  5301  354  448  303  712  1253  2855  5284  338

[6 rows x 42 columns]
Product   PA                                    PB           ...     PE              PF                                 
Cutdata    3    6   12    24    48    96  999    3    6   12 ...     48    96  999    3    6   12    24    48    96  999
Name                                                         ...                                                        
don      380  286  694  1276  2833  5439  318  483  376  727 ...   2687  5278  344  469  334  666  1446  2834  5488  333
kim      468  348  743  1261  2711  5417  310  464  323  626 ...   2579  5238  349  473  358  677  1320  2653  5247  334
micle    459  305  631  1270  2713  5460  333  447  363  758 ...   2863  5283  343  475  344  662  1246  2677  5170  349
park     517  333  680  1227  2751  5290  318  415  361  676 ...   2719  5398  319  448  321  695  1327  2561  5186  307
pop      419  297  729  1210  2784  5314  360  433  315  614 ...   2650  5174  379  452  379  699  1347  2594  5417  319
sally    455  315  682  1420  2627  5203  257  402  327  691 ...   2846  5301  354  448  303  712  1253  2855  5284  338

[6 rows x 42 columns]
timediff : 0.7497549057006836 sec

5. 결과의 사용

groupby를 사용하면 그결과로 컬럼이 Multiindex형태로 나올 수 있습니다. select하기도 쉽지 않고요. 이럴때는 index를 이용하여 join(Dataframe에서는 merge입니다.)하면 됩니다.

참고 코드
import pandas as pd
import time

start = time.time()

df = pd.read_csv("train_long.csv", delimiter=',', header=0)
#print("## All")
#print(df)
 
PRIOD_COND=[-1,3,6,12,24,48,96,999]
PRIOD_labels = ["3", "6", "12", "24", "48","96","999"]
table_dict = {}

cutdata = pd.cut(df["Date"], PRIOD_COND, labels=PRIOD_labels)
df["Cutdata"]=cutdata

#print(df)

#print(df.groupby([df["Name"],df["Product"],df["Cutdata"]]).sum()["Sellcount"])

#print(df.groupby([df["Name"],df["Product"],df["Cutdata"]]).sum()["Sellcount"].unstack(["Product","Cutdata"]))

df_o = df.groupby([df["Name"],df["Product"],df["Cutdata"]]).sum()["Sellcount"].unstack(["Product","Cutdata"])

print(df_o)

df_o=pd.merge(df,df_o,how="left",on='Name')

print(df_o)

print ("timediff :",time.time()-start,"sec")

결과
Product   PA                                    PB           ...     PE              PF                                 
Cutdata    3    6   12    24    48    96  999    3    6   12 ...     48    96  999    3    6   12    24    48    96  999
Name                                                         ...                                                        
don      380  286  694  1276  2833  5439  318  483  376  727 ...   2687  5278  344  469  334  666  1446  2834  5488  333
kim      468  348  743  1261  2711  5417  310  464  323  626 ...   2579  5238  349  473  358  677  1320  2653  5247  334
micle    459  305  631  1270  2713  5460  333  447  363  758 ...   2863  5283  343  475  344  662  1246  2677  5170  349
park     517  333  680  1227  2751  5290  318  415  361  676 ...   2719  5398  319  448  321  695  1327  2561  5186  307
pop      419  297  729  1210  2784  5314  360  433  315  614 ...   2650  5174  379  452  379  699  1347  2594  5417  319
sally    455  315  682  1420  2627  5203  257  402  327  691 ...   2846  5301  354  448  303  712  1253  2855  5284  338

[6 rows x 42 columns]
e:\ProgramData\Anaconda3\lib\site-packages\pandas\core\reshape\merge.py:544: UserWarning: merging between different levels can give an unintended result (1 levels on the left, 2 on the right)
  warnings.warn(msg, UserWarning)
         Name Product  Date  Sellcount Cutdata    ...      (PF, 12)  (PF, 24)  (PF, 48)  (PF, 96)  (PF, 999)
0         pop      PD    68          3      96    ...           699      1347      2594      5417        319
1         kim      PA     1          2       3    ...           677      1320      2653      5247        334
2         don      PA    34          3      48    ...           666      1446      2834      5488        333
3       sally      PE    38          3      48    ...           712      1253      2855      5284        338
4       micle      PA    17          4      24    ...           662      1246      2677      5170        349
5         pop      PB    48          0      48    ...           699      1347      2594      5417        319
6        park      PB    35          0      48    ...           695      1327      2561      5186        307
7       sally      PC    69          4      96    ...           712      1253      2855      5284        338
8       sally      PD     8          0      12    ...           712      1253      2855      5284        338
9       sally      PE    71          1      96    ...           712      1253      2855      5284        338
10       park      PC    96          3      96    ...           695      1327      2561      5186        307
11      micle      PD    11          2      12    ...           662      1246      2677      5170        349
12        pop      PF     0          3       3    ...           699      1347      2594      5417        319
13        don      PB    49          4      96    ...           666      1446      2834      5488        333
14        don      PF    97          2     999    ...           666      1446      2834      5488        333
15       park      PF    21          0      24    ...           695      1327      2561      5186        307
16        kim      PD    37          0      48    ...           677      1320      2653      5247        334
17        pop      PC    72          2      96    ...           699      1347      2594      5417        319
18        don      PF    80          1      96    ...           666      1446      2834      5488        333
19        pop      PA    92          4      96    ...           699      1347      2594      5417        319
20        don      PF    88          2      96    ...           666      1446      2834      5488        333
21        don      PC    38          4      48    ...           666      1446      2834      5488        333
22        pop      PF    68          4      96    ...           699      1347      2594      5417        319
23      sally      PA    96          1      96    ...           712      1253      2855      5284        338
24       park      PA     0          2       3    ...           695      1327      2561      5186        307
25      micle      PD    50          4      96    ...           662      1246      2677      5170        349
26       park      PE    54          2      96    ...           695      1327      2561      5186        307
27      micle      PE     5          3       6    ...           662      1246      2677      5170        349
28        don      PF    89          1      96    ...           666      1446      2834      5488        333
29        kim      PF    32          3      48    ...           677      1320      2653      5247        334
...       ...     ...   ...        ...     ...    ...           ...       ...       ...       ...        ...
199970  sally      PA    53          0      96    ...           712      1253      2855      5284        338
199971   park      PA    27          1      48    ...           695      1327      2561      5186        307
199972  micle      PF    72          3      96    ...           662      1246      2677      5170        349
199973   park      PB    88          2      96    ...           695      1327      2561      5186        307
199974  micle      PC    25          3      48    ...           662      1246      2677      5170        349
199975    pop      PC    53          3      96    ...           699      1347      2594      5417        319
199976    pop      PE    36          3      48    ...           699      1347      2594      5417        319
199977  micle      PC    68          0      96    ...           662      1246      2677      5170        349
199978    don      PF    20          0      24    ...           666      1446      2834      5488        333
199979  sally      PA    21          2      24    ...           712      1253      2855      5284        338
199980  micle      PB    80          3      96    ...           662      1246      2677      5170        349
199981  sally      PF    37          0      48    ...           712      1253      2855      5284        338
199982  sally      PB    87          0      96    ...           712      1253      2855      5284        338
199983    pop      PC    36          0      48    ...           699      1347      2594      5417        319
199984    don      PA    24          4      24    ...           666      1446      2834      5488        333
199985    kim      PD    84          2      96    ...           677      1320      2653      5247        334
199986    kim      PA    51          2      96    ...           677      1320      2653      5247        334
199987    don      PA     6          4       6    ...           666      1446      2834      5488        333
199988    kim      PB    70          4      96    ...           677      1320      2653      5247        334
199989    pop      PE    68          1      96    ...           699      1347      2594      5417        319
199990  micle      PE    96          1      96    ...           662      1246      2677      5170        349
199991    pop      PE     7          4      12    ...           699      1347      2594      5417        319
199992  sally      PD    11          4      12    ...           712      1253      2855      5284        338
199993    kim      PD    15          1      24    ...           677      1320      2653      5247        334
199994  micle      PD    12          0      12    ...           662      1246      2677      5170        349
199995  micle      PD    67          1      96    ...           662      1246      2677      5170        349
199996   park      PC    57          2      96    ...           695      1327      2561      5186        307
199997    don      PF    62          3      96    ...           666      1446      2834      5488        333
199998    pop      PF    54          0      96    ...           699      1347      2594      5417        319
199999    pop      PF    40          1      48    ...           699      1347      2594      5417        319

[200000 rows x 47 columns]
timediff : 1.005450963973999 sec

결과의 column name을 확인해보면 (PF, 12)  (PF, 24)  (PF, 48)  (PF, 96)  (PF, 999) 이런 형태로 이름이 되어있는것을 확인이 됩니다.

6. 큰 데이터의 사용

groupby를 하는 경우 메모리 부족으로 오류가 나는 경우도 있습니다.
이럴때는 일부를 나누어서 합니다. 위 예제에서는 Key가 Name이 되므로 사람 이름별로 한사람씩 하던지 1/2 사람씩 나누어서 select를 한뒤 groupby를 한뒤 결과는 join을 하면 됩니다.
query를 이용한 select하는 예제입니다.
import pandas as pd
import time

start = time.time()

df = pd.read_csv("train_long.csv", delimiter=',', header=0)

cutdata = pd.cut(df["Date"], PRIOD_COND, labels=PRIOD_labels)
df["Cutdata"]=cutdata

df_s = df.query("(Name < 'h')")
print(df_s)
df_s = df.query("(Name >= 'h') and (Name < 'p')")
print(df_s)
df_s = df.query("(Name >= 'p')")
print(df_s)

print ("timediff :",time.time()-start,"sec")

각각의 결과들의 합계는 20만건으로 로딩한 전체 dataframe 크기와 같습니다.
결과
       Name Product  Date  Sellcount Cutdata
2       don      PA    34          3      48
13      don      PB    49          4      96
14      don      PF    97          2     999
18      don      PF    80          1      96
20      don      PF    88          2      96
21      don      PC    38          4      48
28      don      PF    89          1      96
31      don      PC    15          4      24
34      don      PE    52          3      96
36      don      PD    85          4      96
37      don      PE    95          0      96
39      don      PB    91          0      96
40      don      PE    21          3      24
45      don      PA    24          1      24
46      don      PE    55          1      96
50      don      PE    37          3      48
53      don      PA     2          1       3
70      don      PB    40          1      48
81      don      PD    91          1      96
90      don      PC    64          1      96
96      don      PD     5          1       6
103     don      PC    39          3      48
113     don      PC    64          2      96
120     don      PD    33          0      48
125     don      PE    21          4      24
126     don      PE    11          4      12
127     don      PF    14          0      24
128     don      PF    73          2      96
137     don      PC    50          0      96
152     don      PB    37          2      48
...     ...     ...   ...        ...     ...
199815  don      PA    74          3      96
199816  don      PC    84          2      96
199818  don      PC    40          3      48
199820  don      PF    72          3      96
199821  don      PB    90          3      96
199832  don      PF    53          4      96
199853  don      PF    56          1      96
199877  don      PA     9          4      12
199878  don      PA    30          3      48
199879  don      PD    55          2      96
199880  don      PA     1          4       3
199883  don      PD    34          2      48
199893  don      PF    87          1      96
199916  don      PF    15          0      24
199919  don      PE    63          3      96
199927  don      PE    23          4      24
199932  don      PD    28          4      48
199936  don      PF    85          1      96
199939  don      PA    68          3      96
199943  don      PD    88          2      96
199948  don      PB    29          2      48
199955  don      PE    66          4      96
199956  don      PD    26          4      48
199959  don      PE    66          0      96
199961  don      PA    35          4      48
199968  don      PB    87          2      96
199978  don      PF    20          0      24
199984  don      PA    24          4      24
199987  don      PA     6          4       6
199997  don      PF    62          3      96

[33597 rows x 5 columns]
         Name Product  Date  Sellcount Cutdata
1         kim      PA     1          2       3
4       micle      PA    17          4      24
11      micle      PD    11          2      12
16        kim      PD    37          0      48
25      micle      PD    50          4      96
27      micle      PE     5          3       6
29        kim      PF    32          3      48
30      micle      PD    99          4     999
32        kim      PD    75          1      96
38      micle      PB    32          0      48
42      micle      PF    97          1     999
43        kim      PC    40          1      48
51      micle      PE    27          3      48
57        kim      PD     8          3      12
61      micle      PD    26          3      48
65        kim      PD    53          3      96
69      micle      PF    58          1      96
74        kim      PC    53          2      96
77      micle      PF    92          3      96
80      micle      PC    74          0      96
83        kim      PA    64          1      96
85      micle      PF    92          0      96
86        kim      PB    29          4      48
87      micle      PE    36          0      48
89      micle      PB    29          2      48
93      micle      PC    80          1      96
94        kim      PF    12          4      12
95        kim      PA    60          3      96
102     micle      PB    46          4      48
104       kim      PF    13          1      24
...       ...     ...   ...        ...     ...
199915  micle      PE    86          1      96
199917  micle      PF     3          2       3
199921  micle      PF    70          0      96
199922  micle      PE    26          2      48
199924  micle      PD    64          4      96
199928    kim      PC    87          3      96
199933    kim      PF    78          0      96
199934  micle      PE    97          2     999
199937  micle      PE    12          2      12
199938  micle      PC     6          2       6
199941    kim      PE    88          4      96
199947  micle      PC    17          0      24
199949  micle      PF    31          2      48
199951    kim      PC    37          3      48
199958  micle      PB    63          3      96
199962    kim      PD     6          3       6
199963    kim      PB    48          2      48
199967  micle      PA    61          0      96
199969  micle      PD     0          0       3
199972  micle      PF    72          3      96
199974  micle      PC    25          3      48
199977  micle      PC    68          0      96
199980  micle      PB    80          3      96
199985    kim      PD    84          2      96
199986    kim      PA    51          2      96
199988    kim      PB    70          4      96
199990  micle      PE    96          1      96
199993    kim      PD    15          1      24
199994  micle      PD    12          0      12
199995  micle      PD    67          1      96

[66849 rows x 5 columns]
         Name Product  Date  Sellcount Cutdata
0         pop      PD    68          3      96
3       sally      PE    38          3      48
5         pop      PB    48          0      48
6        park      PB    35          0      48
7       sally      PC    69          4      96
8       sally      PD     8          0      12
9       sally      PE    71          1      96
10       park      PC    96          3      96
12        pop      PF     0          3       3
15       park      PF    21          0      24
17        pop      PC    72          2      96
19        pop      PA    92          4      96
22        pop      PF    68          4      96
23      sally      PA    96          1      96
24       park      PA     0          2       3
26       park      PE    54          2      96
33        pop      PB    98          2     999
35        pop      PF    84          4      96
41      sally      PB    17          4      24
44       park      PD    52          3      96
47        pop      PE    38          3      48
48       park      PB    19          0      24
49        pop      PF    43          0      48
52        pop      PB    46          4      48
54      sally      PB    86          0      96
55       park      PF    64          2      96
56        pop      PC    18          0      24
58       park      PE    66          4      96
59      sally      PA     5          0       6
60      sally      PC    32          2      48
...       ...     ...   ...        ...     ...
199935    pop      PA    29          4      48
199940   park      PC    75          1      96
199942   park      PC    19          1      24
199944    pop      PA    60          4      96
199945    pop      PF    14          2      24
199946  sally      PB    72          0      96
199950   park      PA    50          3      96
199952   park      PE    47          1      48
199953   park      PD    44          3      48
199954   park      PC    57          1      96
199957   park      PA     0          3       3
199960    pop      PF    54          1      96
199964    pop      PF    52          1      96
199965  sally      PB    58          3      96
199966  sally      PE    86          2      96
199970  sally      PA    53          0      96
199971   park      PA    27          1      48
199973   park      PB    88          2      96
199975    pop      PC    53          3      96
199976    pop      PE    36          3      48
199979  sally      PA    21          2      24
199981  sally      PF    37          0      48
199982  sally      PB    87          0      96
199983    pop      PC    36          0      48
199989    pop      PE    68          1      96
199991    pop      PE     7          4      12
199992  sally      PD    11          4      12
199996   park      PC    57          2      96
199998    pop      PF    54          0      96
199999    pop      PF    40          1      48

[99554 rows x 5 columns]
timediff : 0.6376185417175293 sec