다음과 같은 데이터 프레임이 있다고 가정 해 보겠습니다.
>>> i = pd.to_datetime(np.random.randint(time.time(), time.time()+10000, 15), unit='ms').sort_values()
>>> df = pd.DataFrame({'A':range(15),'B':range(10,40,2),'C':range(10,55,3)},index = i)
>>> df
A B C
1970-01-19 05:31:36.629 0 10 10
1970-01-19 05:31:36.710 1 12 13
1970-01-19 05:31:37.779 2 14 16
1970-01-19 05:31:38.761 3 16 19
1970-01-19 05:31:39.520 4 18 22
1970-01-19 05:31:39.852 5 20 25
1970-01-19 05:31:39.994 6 22 28
1970-01-19 05:31:41.370 7 24 31
1970-01-19 05:31:41.667 8 26 34
1970-01-19 05:31:42.515 9 28 37
1970-01-19 05:31:42.941 10 30 40
1970-01-19 05:31:43.037 11 32 43
1970-01-19 05:31:43.253 12 34 46
1970-01-19 05:31:43.333 13 36 49
1970-01-19 05:31:44.135 14 38 52
내가 원하는 것은 :
A B C
1970-01-19 05:31:37.779 2.0 14.0 16.0 #last value within 2000 milli-sec interval from 05:31:36
1970-01-19 05:31:38.761 3.0 16.0 19.0 ##last value from the ^ value within 1000 msec interval
1970-01-19 05:31:39.994 6.0 22.0 28.0 #last value within 2000 milli-sec interval from 05:31:38
1970-01-19 05:31:39.994 6.0 22.0 28.0 *##last value from the ^ value within 1000 msec interval
1970-01-19 05:31:41.667 8.0 26.0 34.0 #last value within 2000 milli-sec interval from 05:31:40
1970-01-19 05:31:42.515 9.0 28.0 37.0 ##last value from the ^ value within 1000 msec interval
1970-01-19 05:31:43.333 13.0 36.0 49.0 #last value within 2000 milli-sec interval from 05:31:42
1970-01-19 05:31:44.135 14.0 38.0 52.0 ##last value from the ^ value within 1000 msec interval
#
이 코드 로 s로 표시된 행을 얻을 수 있습니다 .
>>> df.resample('2000ms').ffill().dropna(axis=0)
A B C
1970-01-19 05:31:38 2.0 14.0 16.0
1970-01-19 05:31:40 6.0 22.0 28.0
1970-01-19 05:31:42 8.0 26.0 34.0
1970-01-19 05:31:44 13.0 36.0 49.0
# note I do not care about how the timestamps are getting printed, I just want the correct values.
원하는 결과를 얻을 수있는 pandas 솔루션을 찾을 수 없습니다. 두 개의 데이터 프레임을 사용하여이 작업을 수행 할 수 있습니다. 하나는 샘플링 된 2000ms
것이고 다른 하나는 샘플링 된 1000ms
다음 아마도 루프하고 그에 따라 삽입 할 수 있습니다.
문제는 내 데이터의 실제 크기가 4000000 개 이상의 행과 52 개의 열로 정말 크다는 것입니다. 두 개의 dfs 또는 루프를 피할 수 있다면 확실히하고 싶을 것입니다.
참고 : *
마지막 값에서 1000ms 시간 간격 내에 데이터가 없으므로 표시된 행이 반복되므로 마지막으로 본 값이 반복됩니다. 2000ms 시간 간격에서도 마찬가지입니다.
가능하다면 방법을 보여주세요 ... 감사합니다!
편집 : John Zwinck의 의견에 따라 편집 :
import datetime
def last_time(time):
time = str(time)
start_time = datetime.datetime.strptime(time[11:],'%H:%M:%S.%f')
end_time = start_time + datetime.timedelta(microseconds=1000000)
tempdf = df.between_time(*pd.to_datetime([str(start_time),str(end_time)]).time).iloc[-1]
return tempdf
df['timestamp'] = df.index
df2 = df.resample('2000ms').ffill().dropna(axis=0)
df3 = df2.apply(lambda x:last_time(x['timestamp']), axis = 1)
pd.concat([df2, df3]).sort_index(kind='merge')
이것은 다음을 제공합니다.
A B C timestamp
1970-01-19 05:31:38 2.0 14.0 16.0 1970-01-19 05:31:37.779
1970-01-19 05:31:38 3.0 16.0 19.0 1970-01-19 05:31:38.761
1970-01-19 05:31:40 6.0 22.0 28.0 1970-01-19 05:31:39.994
1970-01-19 05:31:40 6.0 22.0 28.0 1970-01-19 05:31:39.994
1970-01-19 05:31:42 8.0 26.0 34.0 1970-01-19 05:31:41.667
1970-01-19 05:31:42 9.0 28.0 37.0 1970-01-19 05:31:42.515
1970-01-19 05:31:44 13.0 36.0 49.0 1970-01-19 05:31:43.333
1970-01-19 05:31:44 14.0 38.0 52.0 1970-01-19 05:31:44.135
적용 부분이 정말 오래 걸리는 것을 제외하면 괜찮습니다!
더 쉬운 복사를 위해 :
,A,B,C
1970-01-19 05:31:36.629,0,10,10
1970-01-19 05:31:36.710,1,12,13
1970-01-19 05:31:37.779,2,14,16
1970-01-19 05:31:38.761,3,16,19
1970-01-19 05:31:39.520,4,18,22
1970-01-19 05:31:39.852,5,20,25
1970-01-19 05:31:39.994,6,22,28
1970-01-19 05:31:41.370,7,24,31
1970-01-19 05:31:41.667,8,26,34
1970-01-19 05:31:42.515,9,28,37
1970-01-19 05:31:42.941,10,30,40
1970-01-19 05:31:43.037,11,32,43
1970-01-19 05:31:43.253,12,34,46
1970-01-19 05:31:43.333,13,36,49
1970-01-19 05:31:44.135,14,38,52
기존 코드의 느린 부분은를 생성하는 df3
것이므로 최적화하겠습니다.
먼저 last_time(x)
함수가 x에서 x + 1 초까지의 시간 범위 내에서 마지막 레코드를 찾습니다.
루프를 사용하는 대신 전체 벡터에서 시간을 오프셋하여 시작할 수 있습니다.
end_times = df2.timestamp + datetime.timedelta(microseconds=1000000)
그런 다음 numpy.searchsorted()
(매우 과소 평가 된 기능!)을 사용하여 다음 에서 해당 시간을 검색 할 수 있습니다 df
.
idx = np.searchsorted(df.timestamp, end_times)
덧붙여서, df.timestamp.searchsorted(end_times)
같은 일을합니다.
마지막으로, 생성 된 각각의 인덱스는 우리가 원하는 것 (1 초 후의 값을 원하지 않고 바로 앞의 값을 원함) 뒤에 하나씩 있음을 유의하십시오.
df3a = df.iloc[idx - 1]
이것은 df3
인덱스가 반올림되지 않는다는 점을 제외하고 는 동일한 결과를 제공 하므로 교체하십시오.
df3a.index = df2.index
이것은 당신의과 정확히 동일 df3
하지만 훨씬 더 빨리 계산됩니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다