내 데이터는 특정 날짜에 여러 이벤트를 포함하거나 특정 날짜에 이벤트가 없을 수 있습니다. 나는이 사건들을 가지고 날짜별로 카운트를 얻고 그것들을 플로팅합니다. 그러나 내가 그들을 플로팅 할 때 두 시리즈가 항상 일치하지는 않습니다.
idx = pd.date_range(df['simpleDate'].min(), df['simpleDate'].max())
s = df.groupby(['simpleDate']).size()
위의 코드에서 idx 는 30 일의 범위가됩니다. 2013 년 1 월 9 일 ~ 2013 년 9 월 30 일 그러나 S 는 주어진 날짜에 이벤트가 발생하지 않았기 때문에 25 일 또는 26 일 밖에 없을 수 있습니다. 그런 다음 플롯하려고 할 때 크기가 일치하지 않기 때문에 AssertionError가 발생합니다.
fig, ax = plt.subplots()
ax.bar(idx.to_pydatetime(), s, color='green')
이 문제를 해결하는 적절한 방법은 무엇입니까? IDX 에서 값이없는 날짜를 제거하고 싶 습니까? 아니면 (차라리 수행하고 싶습니다) 계수가 0 인 누락 된 날짜를 시리즈에 추가합니다. 차라리 값이 0 인 30 일의 전체 그래프를 갖고 싶습니다. 이 접근 방식이 맞다면 시작하는 방법에 대한 제안이 있습니까? 일종의 동적 reindex
기능이 필요 합니까?
다음은 S ( df.groupby(['simpleDate']).size()
) 의 스 니펫입니다 . 04와 05에는 항목이 없습니다.
09-02-2013 2
09-03-2013 10
09-06-2013 5
09-07-2013 1
답변
다음을 사용할 수 있습니다 Series.reindex
.
import pandas as pd
idx = pd.date_range('09-01-2013', '09-30-2013')
s = pd.Series({'09-02-2013': 2,
'09-03-2013': 10,
'09-06-2013': 5,
'09-07-2013': 1})
s.index = pd.DatetimeIndex(s.index)
s = s.reindex(idx, fill_value=0)
print(s)
수확량
2013-09-01 0
2013-09-02 2
2013-09-03 10
2013-09-04 0
2013-09-05 0
2013-09-06 5
2013-09-07 1
2013-09-08 0
...
답변
더 빠른 해결 방법은 .asfreq()
. 내에서 호출하기 위해 새 색인을 만들 필요가 없습니다 .reindex()
.
# "broken" (staggered) dates
dates = pd.Index([pd.Timestamp('2012-05-01'),
pd.Timestamp('2012-05-04'),
pd.Timestamp('2012-05-06')])
s = pd.Series([1, 2, 3], dates)
print(s.asfreq('D'))
2012-05-01 1.0
2012-05-02 NaN
2012-05-03 NaN
2012-05-04 2.0
2012-05-05 NaN
2012-05-06 3.0
Freq: D, dtype: float64
답변
한 가지 문제는 reindex
중복 값이 있으면 실패 한다는 것입니다. 날짜별로 인덱싱하려는 타임 스탬프 데이터로 작업하고 있다고 가정 해 보겠습니다.
df = pd.DataFrame({
'timestamps': pd.to_datetime(
['2016-11-15 1:00','2016-11-16 2:00','2016-11-16 3:00','2016-11-18 4:00']),
'values':['a','b','c','d']})
df.index = pd.DatetimeIndex(df['timestamps']).floor('D')
df
수확량
timestamps values
2016-11-15 "2016-11-15 01:00:00" a
2016-11-16 "2016-11-16 02:00:00" b
2016-11-16 "2016-11-16 03:00:00" c
2016-11-18 "2016-11-18 04:00:00" d
중복 2016-11-16
날짜 로 인해 재색 인 시도 :
all_days = pd.date_range(df.index.min(), df.index.max(), freq='D')
df.reindex(all_days)
실패 :
...
ValueError: cannot reindex from a duplicate axis
(이로써 인덱스 자체가 중복이 아니라 중복이 있음을 의미합니다)
대신 .loc
다음과 같은 범위의 모든 날짜에 대한 항목을 조회하는 데 사용할 수 있습니다 .
df.loc[all_days]
수확량
timestamps values
2016-11-15 "2016-11-15 01:00:00" a
2016-11-16 "2016-11-16 02:00:00" b
2016-11-16 "2016-11-16 03:00:00" c
2016-11-17 NaN NaN
2016-11-18 "2016-11-18 04:00:00" d
fillna
필요한 경우 공백을 채우기 위해 열 시리즈에 사용할 수 있습니다.
답변
대체 방법은 resample
누락 된 날짜 외에도 중복 날짜를 처리 할 수있는입니다. 예를 들면 :
df.resample('D').mean()
resample
지연된 작업 groupby
이므로 다른 작업을 따라야합니다. 이 사건에서 mean
잘 작동하지만 당신은 또한 같은 많은 다른 팬더 방법을 사용할 수 있습니다 max
, sum
등
다음은 원본 데이터이지만 ‘2013-09-03’에 대한 추가 항목이 있습니다.
val
date
2013-09-02 2
2013-09-03 10
2013-09-03 20 <- duplicate date added to OP's data
2013-09-06 5
2013-09-07 1
결과는 다음과 같습니다.
val
date
2013-09-02 2.0
2013-09-03 15.0 <- mean of original values for 2013-09-03
2013-09-04 NaN <- NaN b/c date not present in orig
2013-09-05 NaN <- NaN b/c date not present in orig
2013-09-06 5.0
2013-09-07 1.0
이것이 어떻게 작동하는지 명확하게하기 위해 누락 된 날짜를 NaN으로 남겨 두었지만 fillna(0)
OP에서 요청한대로 NaN을 0으로 대체하도록 추가 하거나 interpolate()
이웃 행을 기반으로 0이 아닌 값으로 채우는 것과 같은 것을 사용할 수 있습니다.
답변
여기에 좋은의 선택과 더불어, dataframe에 날짜를 누락 채우는 방법이다 fill_value
, days_back
기입하고, 정렬 순서 ( date_order
dataframe을 정렬하는이) :
def fill_in_missing_dates(df, date_col_name = 'date',date_order = 'asc', fill_value = 0, days_back = 30):
df.set_index(date_col_name,drop=True,inplace=True)
df.index = pd.DatetimeIndex(df.index)
d = datetime.now().date()
d2 = d - timedelta(days = days_back)
idx = pd.date_range(d2, d, freq = "D")
df = df.reindex(idx,fill_value=fill_value)
df[date_col_name] = pd.DatetimeIndex(df.index)
return df
답변
![](http://daplus.net/wp-content/uploads/2023/04/coupang_part-e1630022808943-2.png)