팬더가 자동으로 날짜를 인식 할 수 있습니까?


151

오늘 나는 데이터 파일 (예 : 팬더)에서 데이터를 읽는 동안 팬더가 값 유형을 인식 할 수 있다는 사실에 놀랐습니다.

df = pandas.read_csv('test.dat', delimiter=r"\s+", names=['col1','col2','col3'])

예를 들어 다음과 같이 확인할 수 있습니다.

for i, r in df.iterrows():
    print type(r['col1']), type(r['col2']), type(r['col3'])

특히 정수, 부동 소수점 및 문자열이 올바르게 인식되었습니다. 그러나 다음 형식의 날짜가있는 열이 있습니다 2013-6-4. 이 날짜는 파이썬 날짜 객체가 아닌 문자열로 인식되었습니다. 팬더를 인식 된 날짜에 "학습"하는 방법이 있습니까?


이런 종류의 버전에 따른 질문에 대해서는 항상 판다 버전을 명시하십시오. 2013
smci

그리고 dtypes는 각 열에 대해 고정되어 있으므로 df.iterrows()모든 행마다 반복 하고 볼 필요가 없으며 df.info()한 번만 수행하십시오.
smci

답변:


326

일반적으로 마술처럼 파싱하기에 충분한 것을 추가 parse_dates=True하거나 parse_dates=['column name']읽을 때 읽어야합니다. 그러나 수동으로 정의해야하는 이상한 형식이 항상 있습니다. 이 경우 날짜 파서 기능을 추가 할 수 있는데, 이는 가장 유연한 방법입니다.

문자열에 'datetime'열이 있다고 가정하면 다음과 같습니다.

dateparse = lambda x: pd.datetime.strptime(x, '%Y-%m-%d %H:%M:%S')

df = pd.read_csv(infile, parse_dates=['datetime'], date_parser=dateparse)

이렇게하면 여러 열을 단일 날짜 시간 열로 결합 할 수도 있습니다. 이는 '날짜'와 '시간'열을 단일 '날짜 시간'열로 병합합니다.

dateparse = lambda x: pd.datetime.strptime(x, '%Y-%m-%d %H:%M:%S')

df = pd.read_csv(infile, parse_dates={'datetime': ['date', 'time']}, date_parser=dateparse)

대한 (문자는 다른 형식에 사용되는 IE) 당신은 지시를 찾을 수 strptimestrftime 이 페이지에 .


8
나를 위해 작동하지 않았다, 나는 다음과 같은 오류가 발생했습니다 :TypeError: strptime() argument 1 must be str, not float
장 폴

6
데이터 프레임에 난이 있었기 때문에이 오류가 발생했습니다.
Jean Paul

구문 분석 불가능한 재료 나 NaN 또는 / N을 NaT하는 항목을 추가 할 수 있습니까? 그와 같은 것이 있으면이 파서가 전체 열을 완전히 건너 뛰는 것처럼 보입니다.
Amir

infer_datetime_format"팬더는 열에서 날짜 시간 문자열의 형식을 유추하려고 시도합니다" 옵션이 있습니다 . 대신에 사용할 수 있습니다 date_parser.
Winand

1
날짜가 ISO 8601형식이면 전달 infer_datetime_format하거나 파서 기능 을 사용해서는 안됩니다. 팬더가 처리하도록하는 것보다 특히 속도가 느립니다 (특히 후자). 이 답변의
날짜 형식

20

아마도 @Rutger가 응답 한 후 팬더 인터페이스가 변경되었지만 (0.15.2) 버전을 사용하는 경우 date_parser함수가 단일 값 대신 날짜 목록을 수신합니다. 이 경우 그의 코드는 다음과 같이 업데이트되어야합니다.

dateparse = lambda dates: [pd.datetime.strptime(d, '%Y-%m-%d %H:%M:%S') for d in dates]

df = pd.read_csv(infile, parse_dates=['datetime'], date_parser=dateparse)

11

pandas read_csv 메소드는 날짜 구문 분석에 좋습니다. http://pandas.pydata.org/pandas-docs/stable/generated/pandas.io.parsers.read_csv.html 에서 완전한 문서

다른 열에 다른 날짜 부분을 가지고 매개 변수를 전달할 수도 있습니다.

parse_dates : boolean, list of ints or names, list of lists, or dict
If True -> try parsing the index. If [1, 2, 3] -> try parsing columns 1, 2, 3 each as a
separate date column. If [[1, 3]] -> combine columns 1 and 3 and parse as a single date
column. {‘foo : [1, 3]} -> parse columns 1, 3 as date and call result foo

날짜의 기본 감지 기능은 훌륭하지만 북미 날짜 형식에는 편향되어 있습니다. 다른 곳에 산다면 때때로 결과에 걸리기도합니다. 내가 기억할 수있는 한, 1/6/2000은 내가 살고있는 6 월 1 일과 반대로 미국에서 1 월 6 일을 의미합니다. 2000 년 6 월 23 일과 같은 날짜를 사용한다면 그것들을 흔들어 놓는 것이 현명합니다. 그래도 YYYYMMDD 변형 날짜를 유지하는 것이 더 안전합니다. 팬더 개발자에게는 사과하지만 최근 현지 날짜로 테스트하지 않았습니다.

date_parser 매개 변수를 사용하여 형식을 변환하는 함수를 전달할 수 있습니다.

date_parser : function
Function to use for converting a sequence of string columns to an array of datetime
instances. The default uses dateutil.parser.parser to do the conversion.

2
dayfirst유럽 ​​/ 국제 날짜의 경우 True로 지정할 수 있습니다 . pandas.pydata.org/pandas-docs/stable/generated/…
Will Gordon

10

pandas.to_datetime()다음 문서에서 권장 하는 대로 사용할 수 있습니다 pandas.read_csv().

열 또는 인덱스에 구문 분석 할 수없는 날짜가 포함되어 있으면 전체 열 또는 인덱스가 변경되지 않은 상태로 개체 데이터 형식으로 반환됩니다. 비표준 날짜 시간 구문 분석의 경우 pd.to_datetimeafter를 사용하십시오 pd.read_csv.

데모:

>>> D = {'date': '2013-6-4'}
>>> df = pd.DataFrame(D, index=[0])
>>> df
       date
0  2013-6-4
>>> df.dtypes
date    object
dtype: object
>>> df['date'] = pd.to_datetime(df.date, format='%Y-%m-%d')
>>> df
        date
0 2013-06-04
>>> df.dtypes
date    datetime64[ns]
dtype: object

다른 열도 날짜로 변환하고 있으며,이 열은 객체 유형입니다.
ratnesh

10

두 개의 열을 단일 날짜 시간 열에 병합하면 열이 date_parser 함수로 개별적으로 전송되므로 허용되는 응답에서 오류 (팬더 버전 0.20.3)가 생성됩니다.

다음과 같이 작동합니다.

def dateparse(d,t):
    dt = d + " " + t
    return pd.datetime.strptime(dt, '%d/%m/%Y %H:%M:%S')

df = pd.read_csv(infile, parse_dates={'datetime': ['date', 'time']}, date_parser=dateparse)

1
팬더 0.22를 사용하고 있으며 허용되는 답변이 더 이상 작동하지 않는다는 데 동의합니다.
Dai

이것은 "TypeError : str ("float "가 아닌) 만 str에 연결할 수 있습니다"를 만듭니다. 날짜 열은 d / m / y이고 시간 열은 H : M : 00
IceQueeny

8

예- pandas.read_csv 설명서 에 따르면 :

참고 : iso8601 형식의 날짜 에는 빠른 경로가 있습니다 .

따라서 csv에 이름이 지정된 열이 datetime있고 날짜가 예 2013-01-01T01:01를 들면 다음과 같이 실행하면 팬더 (v0.19.2에 있음)가 날짜와 시간을 자동으로 선택합니다.

df = pd.read_csv('test.csv', parse_dates=['datetime'])

명시 적으로 전달해야합니다 parse_dates.없이 작동하지 않습니다.

확인 :

df.dtypes

열의 데이터 유형이 datetime64[ns]


나는 당신이 그 질문을 오해한다고 생각합니다. 사용자는 옵션을 자신의 문자열 형식으로 사용할 수 있는지 궁금합니다.
Arya McCarthy

@AryaMcCarthy 음, 그는 기본적으로 날짜가 올바르게 인식되기를 원하므로 팬더가 자연스럽게 인식하도록 소스 데이터를 변환하는 방법에 대해 언급하고 있습니다. 그가 소스 데이터의 형식을 변경할 수 없다고 언급 한 곳은 없습니다.
Gaurav

1

성능이 중요한 경우 시간을 확보하십시오.

import sys
import timeit
import pandas as pd

print('Python %s on %s' % (sys.version, sys.platform))
print('Pandas version %s' % pd.__version__)

repeat = 3
numbers = 100

def time(statement, _setup=None):
    print (min(
        timeit.Timer(statement, setup=_setup or setup).repeat(
            repeat, numbers)))

print("Format %m/%d/%y")
setup = """import pandas as pd
import io

data = io.StringIO('''\
ProductCode,Date
''' + '''\
x1,07/29/15
x2,07/29/15
x3,07/29/15
x4,07/30/15
x5,07/29/15
x6,07/29/15
x7,07/29/15
y7,08/05/15
x8,08/05/15
z3,08/05/15
''' * 100)"""

time('pd.read_csv(data); data.seek(0)')
time('pd.read_csv(data, parse_dates=["Date"]); data.seek(0)')
time('pd.read_csv(data, parse_dates=["Date"],'
     'infer_datetime_format=True); data.seek(0)')
time('pd.read_csv(data, parse_dates=["Date"],'
     'date_parser=lambda x: pd.datetime.strptime(x, "%m/%d/%y")); data.seek(0)')

print("Format %Y-%m-%d %H:%M:%S")
setup = """import pandas as pd
import io

data = io.StringIO('''\
ProductCode,Date
''' + '''\
x1,2016-10-15 00:00:43
x2,2016-10-15 00:00:56
x3,2016-10-15 00:00:56
x4,2016-10-15 00:00:12
x5,2016-10-15 00:00:34
x6,2016-10-15 00:00:55
x7,2016-10-15 00:00:06
y7,2016-10-15 00:00:01
x8,2016-10-15 00:00:00
z3,2016-10-15 00:00:02
''' * 1000)"""

time('pd.read_csv(data); data.seek(0)')
time('pd.read_csv(data, parse_dates=["Date"]); data.seek(0)')
time('pd.read_csv(data, parse_dates=["Date"],'
     'infer_datetime_format=True); data.seek(0)')
time('pd.read_csv(data, parse_dates=["Date"],'
     'date_parser=lambda x: pd.datetime.strptime(x, "%Y-%m-%d %H:%M:%S")); data.seek(0)')

인쇄물:

Python 3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 03:13:28) 
[Clang 6.0 (clang-600.0.57)] on darwin
Pandas version 0.23.4
Format %m/%d/%y
0.19123052499999993
8.20691274
8.143124389
1.2384357139999977
Format %Y-%m-%d %H:%M:%S
0.5238807110000039
0.9202787830000005
0.9832778819999959
12.002349824999996

그래서 ISO8601 형식의 날짜 ( %Y-%m-%d %H:%M:%S명백하게 ISO8601 형식의 날짜, 나는 T 추측입니다 삭제할 수 있습니다 당신이해야하고 공백으로 대체) 되지 지정 infer_datetime_format(하나 분명히 일반적인 사람과 차이를하지 않습니다)하고 자신의 통과 파서가 성능을 저하시킵니다. 반면에 date_parser표준 요일 형식과 다르지 않습니다. 평소처럼 최적화하기 전에 시간을 정하십시오.


1

csv 파일을로드하는 동안 날짜 열이 포함되어 있습니다. 팬더가 날짜 열을 인식하도록하는 두 가지 방법이 있습니다.

  1. 팬더는 명시 적으로 arg로 형식을 인식합니다. date_parser=mydateparser

  2. 팬더는 암시 적으로 형식을 인식합니다. infer_datetime_format=True

날짜 열 데이터 중 일부

01/01/18

01/02/18

여기서 우리는 처음 두 가지를 알지 못합니다. 월 또는 일 일 수 있습니다. 따라서이 경우 방법 1을 사용해야합니다.

    mydateparser = lambda x: pd.datetime.strptime(x, "%m/%d/%y")
    df = pd.read_csv(file_name, parse_dates=['date_col_name'],
date_parser=mydateparser)

방법 2 :-형식을 암시 적 또는 자동으로 인식

df = pd.read_csv(file_name, parse_dates=[date_col_name],infer_datetime_format=True)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.