FinanceData / marcap

market cap datasets (1995~2021 daily, 10 million+ rows)
259 stars 93 forks source link

marcap_data 호출시 에러가 발생합니다. #6

Closed choco529 closed 3 years ago

choco529 commented 3 years ago

marcap_data 함수를 호출하면 다음과 같은 에러가 발생합니다. image

df_list에 왜 데이터가 없는지 살펴봤더니 csv를 read할 때 다음과 같은 에러가 발생했었습니다.


TypeErrorTraceback (most recent call last) pandas_libs\parsers.pyx in pandas._libs.parsers.TextReader._convert_tokens()

TypeError: Cannot cast array from dtype('float64') to dtype('int32') according to the rule 'safe'

During handling of the above exception, another exception occurred:

ValueErrorTraceback (most recent call last)

in 4 'MarketId':str, 'Market':str, 'Dept':str, 5 'Rank':int} ----> 6 df = pd.read_csv(csv_file, dtype=dtypes, parse_dates=['Date']) C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\parsers.py in read_csv(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, squeeze, prefix, mangle_dupe_cols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, dialect, error_bad_lines, warn_bad_lines, delim_whitespace, low_memory, memory_map, float_precision, storage_options) 608 kwds.update(kwds_defaults) 609 --> 610 return _read(filepath_or_buffer, kwds) 611 612 C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\parsers.py in _read(filepath_or_buffer, kwds) 466 467 with parser: --> 468 return parser.read(nrows) 469 470 C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\parsers.py in read(self, nrows) 1055 def read(self, nrows=None): 1056 nrows = validate_integer("nrows", nrows) -> 1057 index, columns, col_dict = self._engine.read(nrows) 1058 1059 if index is None: C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\parsers.py in read(self, nrows) 2059 def read(self, nrows=None): 2060 try: -> 2061 data = self._reader.read(nrows) 2062 except StopIteration: 2063 if self._first_chunk: pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader.read() pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader._read_low_memory() pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader._read_rows() pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader._convert_column_data() pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader._convert_tokens() **ValueError: cannot safely convert passed user dtype of int32 for float64 dtyped data in column 12** ---------------------------------------------------------------------------------------------- python 버전은 3.7.4 이며 pandas 버전은 1.2.2 입니다.
stat17-hb commented 3 years ago

저도 같은 문제가 있어서 코드 뜯어봤었는데 데이터 타입 정의 문제 때문인 것 같아서 그 부분만 고치고 사용하고 있습니다.

from datetime import datetime
import numpy as np
import pandas as pd

def marcap_data(start, end=None, code=None):
    '''
    지정한 기간 데이터 가져오기
    :param datetime start: 시작일
    :param datetime end: 종료일 (지정하지 않으면 시작일과 동일)
    :param str code: 종목코드 (지정하지 않으면 모든 종목)
    :return: DataFrame
    '''
    start = pd.to_datetime(start)
    end = start if end==None else pd.to_datetime(end)
    df_list = []

#     dtypes={'Code':str, 'Name':str, 
#             'Open':int, 'High':int, 'Low':int, 'Close':int, 'Volume':int, 'Amount':int,
#             'Changes':int, 'ChangeCode':str, 'ChagesRatio':float, 'Marcap':int, 'Stocks':int,
#             'MarketId':str, 'Market':str, 'Dept':str,
#             'Rank':int}

# Amount, Marcap을 int 타입으로 변환할 수 없다는 에러메시지 발생

    dtypes={'Code':str, 'Name':str, 
            'Open':int, 'High':int, 'Low':int, 'Close':int, 'Volume':int, 'Amount':float,
            'Changes':int, 'ChangeCode':str, 'ChagesRatio':float, 'Marcap':float, 'Stocks':int,
            'MarketId':str, 'Market':str, 'Dept':str,
            'Rank':int}

    for year in range(start.year, end.year + 1):
        try:
            csv_file = 'marcap/data/marcap-%s.csv.gz' % (year)
            df = pd.read_csv(csv_file, dtype=dtypes, parse_dates=['Date'])
            df_list.append(df)
        except Exception as e:
            print(e)
            pass
    df_merged = pd.concat(df_list)
    df_merged = df_merged[(start <= df_merged['Date']) & (df_merged['Date'] <= end)]  
    df_merged = df_merged.sort_values(['Date','Rank'])
    if code:
        df_merged = df_merged[code == df_merged['Code']]  
    df_merged.set_index('Date', inplace=True)
    return df_merged[df_merged['Volume'] > 0]
FinanceData commented 3 years ago

우분투 리눅스(python: 3.8.8, pandas: 1.2.4)와 구글 Colab(python: 3.7.10, pandas: 1.1.5)에서 문제가 없었습니다.

윈도우 아나콘다(python: 3.7.6, pandas: 1.2.4, 1.2.5 둘 다)에서 위 에러가 발생하는 것을 확인하였습니다. pd.concat()에서 타입 변환에 따른 문제로 생각됩니다.

수정하여 사용하신 내용을 그대로 반영하였습니다.

이슈 라이징과 해결 답변 모두 감사합니다.