Pandas Datetime 열과 별도로 월과 연도 추출


221

다음 열이있는 데이터 프레임 df가 있습니다.

df['ArrivalDate'] =
...
936   2012-12-31
938   2012-12-29
965   2012-12-31
966   2012-12-31
967   2012-12-31
968   2012-12-31
969   2012-12-31
970   2012-12-29
971   2012-12-31
972   2012-12-29
973   2012-12-29
...

열의 요소는 pandas.tslib.Timestamp입니다.

연도와 월만 포함하고 싶습니다. 나는 그것을 할 수있는 간단한 방법이있을 것이라고 생각했지만 이해할 수는 없습니다.

내가 시도한 것은 다음과 같습니다.

df['ArrivalDate'].resample('M', how = 'mean')

다음과 같은 오류가 발생했습니다.

Only valid with DatetimeIndex or PeriodIndex 

그런 다음 시도했습니다.

df['ArrivalDate'].apply(lambda(x):x[:-2])

다음과 같은 오류가 발생했습니다.

'Timestamp' object has no attribute '__getitem__' 

어떤 제안?

편집 : 나는 그것을 알아 냈습니다.

df.index = df['ArrivalDate']

그런 다음 인덱스를 사용하여 다른 열을 다시 샘플링 할 수 있습니다.

그러나 여전히 전체 열을 재구성하는 방법을 원합니다. 어떤 아이디어?


11
최적의 응답은 .. DF 명확 [ 'mnth_yr'] = df.date_column.dt.to_period ( 'M') @ jaknap32에서 아래와 같이
ihightower

1
당신은 할 필요조차 없습니다 to_period: df.date_column.dt.month(또는 .year, 또는 .day) 작품
elz


2
@elphz : .dt.month그래도 1 년을 잃습니다. 그리고 .dt.to_period('M')데이터 유형을 더 이상 datetime64가 아닌 것으로 변경합니다. 나는 값을 자르 라고 제안 하는 Juan의 대답을 사용했습니다 .astype('datetime64[M]').
Nickolay

최고의 답변을 변경할 수 있습니까?
Gonzalo Garcia

답변:


306

연도 및 월을 별도로 표시하는 새 열을 원할 경우 다음을 수행 할 수 있습니다.

df['year'] = pd.DatetimeIndex(df['ArrivalDate']).year
df['month'] = pd.DatetimeIndex(df['ArrivalDate']).month

또는...

df['year'] = df['ArrivalDate'].dt.year
df['month'] = df['ArrivalDate'].dt.month

그런 다음 그대로 사용하거나 그대로 사용할 수 있습니다.


7
한 줄로 이것을 할 수있는 방법이 있습니까? 동일한 열을 여러 번 통과하지 않도록하고 싶습니다.
fixxxer 2016

2
일부 빠른 벤치마킹 timeit을 통해 DatetimeIndex접근 방식이 .map/.apply또는 보다 훨씬 빠릅니다 .dt.
Snorfalorpagus

2
가장 좋은 대답은 명확합니다. df [ 'mnth_yr'] = df.date_column.dt.to_period ( 'M') @ jaknap32에서 다음과 같이
ihightower

pd.Datetimeindex는 실제로 무엇을합니까?
JOHN

나는 때때로 이것을한다 : df['date_column_trunc'] = df[date_column'].apply(lambda s: datetime.date(s.year, s.month, 1)
Stewbaca

229

가장 좋은 방법은 발견 !

df['date_column']날짜 시간 형식이어야한다.

df['month_year'] = df['date_column'].dt.to_period('M')

다른 샘플링 간격에 D대해 Day, 2M2 개월 등을 사용할 수도 있고 타임 스탬프가있는 시계열 데이터가있는 경우 45Min45 분, 15Min15 분 샘플링 등의 세부 샘플링 간격으로 갈 수 있습니다 .


8
결과 열은 datetime64더 이상 dtype 이 아닙니다 . @Juan의 답변df.my_date_column.astype('datetime64[M]') 에서처럼을 사용하면 매월 첫 번째 날을 나타내는 날짜로 변환됩니다.
Nickolay

3
나는 이것이 여기
Tim

154

yearmonth속성에 직접 액세스 하거나 다음을 요청할 수 있습니다 datetime.datetime.

In [15]: t = pandas.tslib.Timestamp.now()

In [16]: t
Out[16]: Timestamp('2014-08-05 14:49:39.643701', tz=None)

In [17]: t.to_pydatetime() #datetime method is deprecated
Out[17]: datetime.datetime(2014, 8, 5, 14, 49, 39, 643701)

In [18]: t.day
Out[18]: 5

In [19]: t.month
Out[19]: 8

In [20]: t.year
Out[20]: 2014

연도와 월을 결합하는 한 가지 방법은 다음과 같이 정수를 인코딩하는 것입니다 201408. 2014 년 8 월의 경우 전체 열을 따라 다음과 같이 할 수 있습니다.

df['YearMonth'] = df['ArrivalDate'].map(lambda x: 100*x.year + x.month)

또는 그의 많은 변형.

그래도 날짜 조정 및 산술이 나중에 고통스럽고 특히 동일한 규칙없이 코드 또는 데이터를 사용하는 다른 사람들에게 고통 스럽기 때문에 나는 이것을하는 데 큰 팬이 아닙니다. 더 나은 방법은 미국의 휴일이 아닌 요일 또는 첫날과 같은 월별 규칙을 선택하고 선택한 날짜 규칙을 사용하여 날짜 / 시간 형식으로 데이터를 남겨 두는 것입니다.

calendar모듈은 마지막 요일과 같은 특정 요일의 숫자 값을 얻는 데 유용합니다. 그런 다음 다음과 같은 작업을 수행 할 수 있습니다.

import calendar
import datetime
df['AdjustedDateToEndOfMonth'] = df['ArrivalDate'].map(
    lambda x: datetime.datetime(
        x.year,
        x.month,
        max(calendar.monthcalendar(x.year, x.month)[-1][:5])
    )
)

datetime 열을 문자열로 표현하는 간단한 문제를 해결하는 방법을 찾고 있다면 다음 과 같이 클래스 의 strftime함수를 사용할 수 있습니다 datetime.datetime.

In [5]: df
Out[5]: 
            date_time
0 2014-10-17 22:00:03

In [6]: df.date_time
Out[6]: 
0   2014-10-17 22:00:03
Name: date_time, dtype: datetime64[ns]

In [7]: df.date_time.map(lambda x: x.strftime('%Y-%m-%d'))
Out[7]: 
0    2014-10-17
Name: date_time, dtype: object

4
성능이 나빠질 수 있으므로 항상 도우미 기능, 벡터화 된 작업 및 pandas분할 적용 조합 기술을 최대한 활용하는 것이 좋습니다 . 위의 제 제안은 귀하의 경우에 가장 성능이 좋은 접근 방법이라는 보증서가 아닙니다. 단지 다양한 경우에 대해 스타일 적으로 유효한 Pythonic 선택이라는 것입니다.
ely

@KieranPC의 아래 답변은 훨씬 빠릅니다
Ben

2
가장 좋은 대답은 명확합니다. df [ 'mnth_yr'] = df.date_column.dt.to_period ( 'M') @ jaknap32에서 다음과 같이
ihightower

2
에 100을 곱해야합니다 df['YearMonth'] = df['ArrivalDate'].map(lambda x: 1000*x.year + x.month).
Git Gud

1
@ zthomas.nc 나는 그들이 그것을 해결하는 두 가지 매우 다른 방법을 제공하기 때문에 두 개의 별도 답변으로 더 잘 작동한다고 생각합니다.
ely

34

당신이 달 년 독특한 쌍을 원한다면, apply를 사용하는 것이 매우 매끄 럽습니다.

df['mnth_yr'] = df['date_column'].apply(lambda x: x.strftime('%B-%Y')) 

한 열에 월-년을 출력합니다.

먼저 형식을 날짜-시간으로 변경하는 것을 잊지 마십시오. 일반적으로 잊어 버립니다.

df['date_column'] = pd.to_datetime(df['date_column'])

람다 기능도 피할 수 있습니다.df['month_year'] = df['date_column'].dt.strftime('%B-%Y')
Rishabh

13

[ '2018-03-04']에서 연도 추출

df['Year'] = pd.DatetimeIndex(df['date']).year  

df [ 'Year']는 새로운 열을 만듭니다. 월을 추출하려면 .month를 사용하십시오.


1
감사합니다. date_1 = pd.DatetimeIndex (df [ 'date']) --year = date_1.year # 년 동안---month = date_1.month # 달 동안---dy = date_1. 일 # 일 동안
Edwin Torres

7

먼저 pandas.to_datetime으로 날짜 문자열을 변환 하면 모든 numpy 날짜 시간 및 timedelta 기능 에 액세스 할 수 있습니다. 예를 들면 다음과 같습니다.

df['ArrivalDate'] = pandas.to_datetime(df['ArrivalDate'])
df['Month'] = df['ArrivalDate'].values.astype('datetime64[M]')

pyspark 's와 유사한 기능을 찾고 있었기 때문에 이것은 정말 잘 작동했습니다 trunc. astype('datetime64[M]')컨벤션에 대한 문서가 있습니까?
h1-the-swan

6

jaknap32 덕분에 Year와 Month에 따라 결과를 집계하고 싶었습니다.

df_join['YearMonth'] = df_join['timestamp'].apply(lambda x:x.strftime('%Y%m'))

깔끔한 출력 :

0    201108
1    201108
2    201108

6

@KieranPC의 솔루션 은 Pandas에 대한 올바른 접근 방법이지만 임의의 속성에 대해서는 쉽게 확장 할 수 없습니다. 이를 위해 getattr발전기 이해 내에서 사용하고 pd.concat다음을 사용하여 결합 할 수 있습니다 .

# input data
list_of_dates = ['2012-12-31', '2012-12-29', '2012-12-30']
df = pd.DataFrame({'ArrivalDate': pd.to_datetime(list_of_dates)})

# define list of attributes required    
L = ['year', 'month', 'day', 'dayofweek', 'dayofyear', 'weekofyear', 'quarter']

# define generator expression of series, one for each attribute
date_gen = (getattr(df['ArrivalDate'].dt, i).rename(i) for i in L)

# concatenate results and join to original dataframe
df = df.join(pd.concat(date_gen, axis=1))

print(df)

  ArrivalDate  year  month  day  dayofweek  dayofyear  weekofyear  quarter
0  2012-12-31  2012     12   31          0        366           1        4
1  2012-12-29  2012     12   29          5        364          52        4
2  2012-12-30  2012     12   30          6        365          52        4

1
df['year_month']=df.datetime_column.apply(lambda x: str(x)[:7])

이것은 나를 위해 잘 작동했습니다. 팬더가 결과 문자열 날짜를 날짜로 해석하지 않았다고 생각했지만 플롯을했을 때 내 의제와 문자열을 올바르게 주문한 연도 월을 잘 알았습니다 ... 팬더를 사랑해야합니다!


1

방법 적용을 사용하지 않고 모든 데이터 프레임의 연도를 추출하는 두 단계가 있습니다.

1 단계

열을 날짜 시간으로 변환하십시오.

df['ArrivalDate']=pd.to_datetime(df['ArrivalDate'], format='%Y-%m-%d')

2 단계

DatetimeIndex()방법을 사용하여 연도 또는 월을 추출

 pd.DatetimeIndex(df['ArrivalDate']).year

1

단일 라인 : '년-월'쌍으로 열 추가 : ( 'pd.to_datetime'은 먼저 열 dtype을 작업 전 날짜-시간으로 변경합니다)

df['yyyy-mm'] = pd.to_datetime(df['ArrivalDate']).dt.strftime('%Y-%m')

따라서 추가 '연도'또는 '월'열의 경우 :

df['yyyy'] = pd.to_datetime(df['ArrivalDate']).dt.strftime('%Y')

df['mm'] = pd.to_datetime(df['ArrivalDate']).dt.strftime('%m')
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.