2017-09-04 1 views
0

데이터베이스에서 날짜를 가져 오는 데 cx_oracle을 사용하고 있습니다. 가져온 데이터를 판다 데이터 프레임에 넣고 싶습니다. 내 문제는 날짜가 절대적으로 필요하지 않은 numpy.datetime64 개체로 변환된다는 것입니다.pandas 데이터 프레임 열에 datetime.date 유형이 포함될 수 있습니까?

나는 이것을 datetime.date 객체로 갖고 싶습니다. dt.date 메서드를 보았지만 여전히 numpy 데이터 형식을 반환합니다.

답변

4

편집 : 팬더 0.21.0 이상을 사용하면 파이썬 datetime.date을 DataFrame에 유지하는 데 문제가없는 것으로 보입니다. date-like 열은 datetime64[ns] dtype으로 자동 변환되지 않습니다. 팬더의 이전 버전

import numpy as np 
import pandas as pd 
import datetime as DT 

print(pd.__version__) 
# 0.21.0.dev+25.g50e95e0 
dates = [DT.date(2017,1,1)+DT.timedelta(days=2*i) for i in range(3)] 
df = pd.DataFrame({'dates': dates, 'foo': np.arange(len(dates))}) 
print(all([isinstance(item, DT.date) for item in df['dates']])) 
# True 
df['dates'] = (df['dates'] + pd.Timedelta(days=1)) 
print(all([isinstance(item, DT.date) for item in df['dates']])) 
# True 

:

자동으로 이러한 빈 문자열 로 추가로 값을 할당하여 datetime64[ns]에 datelike 값을 변환에서 팬더 DataFrame을 방지 할 수있는 방법이되는 열에과 같은 것이 아닙니다. DataFrame이 형성 후에는 비 datelike 값을 제거 할 수 있습니다 : 우리는 개발자의 의도를 전복하고 있기 때문에

import pandas as pd 
import datetime as DT 
dates = [DT.date(2017,1,1)+DT.timedelta(days=i) for i in range(10)] 
df = pd.DataFrame({'dates':['']+dates}) 
df = df.iloc[1:] 
print(all([isinstance(item, DT.date) for item in df['dates']])) 
# True 

은 분명히 심각한 코드로 shenanigan 이런 종류의 프로그래밍을하는 것은 완전히 잘못된 느낀다. 목록 또는 객체 배열 datetime.dates에 대해 datetime64[ns] 초를 사용하면 계산 속도면에서 장점이 있습니다. 또한, df[col] 파이썬 datetime.date의의 객체 NumPy와 배열 반환 df[col].dt.date.values 다음 DTYPE datetime64[ns]이있는 경우 : datetime64[ns]로 열을 유지하고 datetime.date의를 얻기 위해 df[col].dt.date.values를 사용하여

import pandas as pd 
import datetime as DT 
dates = [DT.datetime(2017,1,1)+DT.timedelta(days=2*i) for i in range(3)] 
df = pd.DataFrame({'dates': dates}) 
print(repr(df['dates'].dt.date.values)) 
# array([datetime.date(2017, 1, 1), datetime.date(2017, 1, 3), 
#  datetime.date(2017, 1, 5)], dtype=object) 

그래서 당신은 아마도 두 세계의 최고를 즐길 수를 필요할 땐.

한편, datetime64[ns]과 Python datetime.date에는 표현할 수있는 범위의 범위가 다릅니다.

  • datetime64[ns]1678 AD to 2262 AD의 datetimes를 나타낼 수 있습니다.
  • datetime.dateDT.date(0,1,1)부터 DT.date(9999,1,1)까지의 날짜를 나타낼 수 있습니다.

당신이 datetime.date를 사용하려는 이유는 datetime64[ns]의 대신 s의 경우는, 표현 가능한 날짜의 제한 범위를 극복하기 위해 아마도 a better alternative is to use a pd.PeriodIndex입니다 :

import pandas as pd 
import datetime as DT 
dates = [DT.date(2017,1,1)+DT.timedelta(days=2*i) for i in range(10)] 
df = pd.DataFrame({'dates':pd.PeriodIndex(dates, freq='D')}) 
print(df) 
#  dates 
# 0 2017-01-01 
# 1 2017-01-03 
# 2 2017-01-05 
# 3 2017-01-07 
# 4 2017-01-09 
# 5 2017-01-11 
# 6 2017-01-13 
# 7 2017-01-15 
# 8 2017-01-17 
# 9 2017-01-19 
관련 문제