다음과 같이 csv에서 데이터 프레임을 만들고 있습니다:
stock = pd.read_csv('data_in/' + filename + '.csv', skipinitialspace=True)
데이터 프레임에 날짜 열이 있습니다. 지정된 날짜 범위 내에 있거나 지정된 두 날짜 값 사이에 있는 날짜 값이 있는 행만 포함하는 새 데이터 프레임을 만들거나 기존 데이터 프레임을 덮어쓸 수 있는 방법이 있나요?
두 가지 가능한 해결책이 있습니다:
df.loc[mask]
를 사용합니다.df[start_date : end_date]
를 사용합니다.부울 마스크 사용:
df['date']가 dtype
datetime64[ns]`를 가진 시리즈인지 확인합니다:
df['date'] = pd.to_datetime(df['date'])
부울 마스크를 만듭니다. start_date및
end_date는
datetime.datetime일 수 있습니다, np.datetime64
, pd.Timestamp
, 또는 날짜 문자열일 수도 있습니다:
#greater than the start date and smaller than the end date
mask = (df['date'] > start_date) & (df['date'] <= end_date)
하위 데이터프레임을 선택합니다:
df.loc[mask]
또는 df
에 재할당
df = df.loc[mask]
예를 들어
임포트 넘피를 np로
임포트 판다를 pd로
df = pd.DataFrame(np.random.random((200,3)))
df['date'] = pd.date_range('2000-1-1', periods=200, freq='D')
mask = (df['date'] > '2000-6-1') & (df['date'] <= '2000-6-10')
print(df.loc[mask])
yields
0 1 2 date
153 0.208875 0.727656 0.037787 2000-06-02
154 0.750800 0.776498 0.237716 2000-06-03
155 0.812008 0.127338 0.397240 2000-06-04
156 0.639937 0.207359 0.533527 2000-06-05
157 0.416998 0.845658 0.872826 2000-06-06
158 0.440069 0.338690 0.847545 2000-06-07
159 0.202354 0.624833 0.740254 2000-06-08
160 0.465746 0.080888 0.155452 2000-06-09
161 0.858232 0.190321 0.432574 2000-06-10
DatetimeIndex](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#partial-string-indexing) 사용:
날짜별로 많은 선택을 수행하려는 경우 먼저 인덱스로
날짜열을 인덱스로 먼저 설정하는 것이 더 빠를 수 있습니다. 그런 다음 다음을 사용하여 날짜별로 행을 선택할 수 있습니다. df.loc[start_date:end_date]
를 사용하여 날짜별로 행을 선택할 수 있습니다.
numpy를 np로 가져옵니다.
임포트 팬더로 pd
df = pd.DataFrame(np.random.random((200,3)))
df['date'] = pd.date_range('2000-1-1', periods=200, freq='D')
df = df.set_index(['date'])
print(df.loc['2000-6-1':'2000-6-10'])
yields
0 1 2
date
2000-06-01 0.040457 0.326594 0.492136 # <- includes start_date
2000-06-02 0.279323 0.877446 0.464523
2000-06-03 0.328068 0.837669 0.608559
2000-06-04 0.107959 0.678297 0.517435
2000-06-05 0.131555 0.418380 0.025725
2000-06-06 0.999961 0.619517 0.206108
2000-06-07 0.129270 0.024533 0.154769
2000-06-08 0.441010 0.741781 0.470402
2000-06-09 0.682101 0.375660 0.009916
2000-06-10 0.754488 0.352293 0.339337
파이썬 리스트 인덱싱(예: seq[start:end]
)은 start
는 포함하지만 end
는 포함하지 않지만, 이와 대조적으로, Pandas df.loc[start_date : end_date]
는 끝점이 인덱스에 있는 경우 결과에 두 끝점을 모두 포함합니다. 그러나 start_date
나 end_date
모두 인덱스에 있을 필요는 없습니다.
또한 pd.read_csv
에는 parse_dates
매개변수가 있어 date
열을 datetime64
로 구문 분석하는 데 사용할 수 있다는 점에 유의하세요. 따라서 parse_dates
를 사용하는 경우 df['date'] = pd.to_datetime(df['date'])
를 사용할 필요가 없습니다.
다음과 같이 date
열에 isin
메서드를 사용할 수 있습니다.
df[df["date"].isin(pd.date_range(start_date, end_date))]
**참고: 이 방법은 타임스탬프가 아닌 날짜(질문에서 질문한 대로)에만 작동합니다.
예:
import numpy as np
import pandas as pd
# Make a DataFrame with dates and random numbers
df = pd.DataFrame(np.random.random((30, 3)))
df['date'] = pd.date_range('2017-1-1', periods=30, freq='D')
# Select the rows between two dates
in_range_df = df[df["date"].isin(pd.date_range("2017-01-15", "2017-01-20"))]
print(in_range_df) # print result
는
0 1 2 date
14 0.960974 0.144271 0.839593 2017-01-15
15 0.814376 0.723757 0.047840 2017-01-16
16 0.911854 0.123130 0.120995 2017-01-17
17 0.505804 0.416935 0.928514 2017-01-18
18 0.204869 0.708258 0.170792 2017-01-19
19 0.014389 0.214510 0.045201 2017-01-20
이 것은 단순한 솔루션 및 파이썬, 꼭 이래야겠어요 시도하시려면 것이 좋습니다.
이 경우 예정이면 자주 할 수 있는 최적의 솔루션을 약간만이라도 날짜 열 예정인 첫 세트를 인덱스화할 변환하십시오 열에 따라 다음 조건을 모든 날짜 범위를 슬라이스에 다테이메이네스 및 사용.
import pandas as pd
data_frame = data_frame.set_index('date')
df = data_frame[(data_frame.index > '2017-08-10') & (data_frame.index <= '2017-08-15')]
내가 아닌 포지셔닝하십시오 변경하십시오 'df'.
옵션으로 '는' 의 '시작' 과 '끝' 읽어들이려면 인덱스화할 날짜:
import numpy as np
import pandas as pd
#Dummy DataFrame
df = pd.DataFrame(np.random.random((30, 3)))
df['date'] = pd.date_range('2017-1-1', periods=30, freq='D')
#Get the index of the start and end dates respectively
start = df[df['date']=='2017-01-07'].index[0]
end = df[df['date']=='2017-01-14'].index[0]
#Show the sliced df (from 2017-01-07 to 2017-01-14)
df.loc[start:end]
이로 인해:
0 1 2 date
6 0.5 0.8 0.8 2017-01-07
7 0.0 0.7 0.3 2017-01-08
8 0.8 0.9 0.0 2017-01-09
9 0.0 0.2 1.0 2017-01-10
10 0.6 0.1 0.9 2017-01-11
11 0.5 0.3 0.9 2017-01-12
12 0.5 0.4 0.3 2017-01-13
13 0.4 0.9 0.9 2017-01-14
내가 사용하는 테스트 버전인 '의' 판다 '이 질문에 답하는 0.22.0' 이제 좀 더 쉽게 읽을 수 있는 코드를 사용하는 것만으로 '간'.
# create a single column DataFrame with dates going from Jan 1st 2018 to Jan 1st 2019
df = pd.DataFrame({'dates':pd.date_range('2018-01-01','2019-01-01')})
27일 11월 2018년, s # 39 라고 let& 날짜: 15일 1월 2019년 사이에 운영까지도 잡기 위한 및
# use the between statement to get a boolean mask
df['dates'].between('2018-11-27','2019-01-15', inclusive=False)
0 False
1 False
2 False
3 False
4 False
# you can pass this boolean mask straight to loc
df.loc[df['dates'].between('2018-11-27','2019-01-15', inclusive=False)]
dates
331 2018-11-28
332 2018-11-29
333 2018-11-30
334 2018-12-01
335 2018-12-02
디이브이 포함) 이 인수. 원하는걸까요 명시성 때 매우 유용한 정보 범위. 27일 11월 2018년 복귀하십시오 디이브이 true 로 설정할 때 우리는 잘 알려져 있다.
df.loc[df['dates'].between('2018-11-27','2019-01-15', inclusive=True)]
dates
330 2018-11-27
331 2018-11-28
332 2018-11-29
333 2018-11-30
334 2018-12-01
이 방법은 또한 보다 앞서 언급한 '이신' 방법:
%%timeit -n 5
df.loc[df['dates'].between('2018-11-27','2019-01-15', inclusive=True)]
868 µs ± 164 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)
%%timeit -n 5
df.loc[df['dates'].isin(pd.date_range('2018-01-01','2019-01-01'))]
1.53 ms ± 305 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)
그러나, 보다 빠른 것은 현재 수락됨 오토메이티드 크누트부 제공하는 경우에 한해 마스크는 이미 작성된. 하지만, 내 방식을 운명인것 재지정됨 마스크할 동적입니다 및 합니다 더 효율적으로 사용할 수 있습니다.
# already create the mask THEN time the function
start_date = dt.datetime(2018,11,27)
end_date = dt.datetime(2019,1,15)
mask = (df['dates'] > start_date) & (df['dates'] <= end_date)
%%timeit -n 5
df.loc[mask]
191 µs ± 28.5 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)