我正在is_holiday
列中手动填充一些分类标签。有些行只有第一个观察结果带有正确的标签,其余的为0,我将这些零填满:
# Before filling
print(main_data.loc["25 December, 2012"].is_holiday)
date_time
2012-12-25 00:00:00 3
2012-12-25 01:00:00 0
2012-12-25 02:00:00 0
2012-12-25 03:00:00 0
.
.
.
2012-12-25 19:00:00 0
2012-12-25 20:00:00 0
2012-12-25 21:00:00 0
2012-12-25 22:00:00 0
2012-12-25 23:00:00 0
Name: is_holiday, dtype: int64
# Manually fill
for row in range(len(main_data.loc["2012"])):
if main_data.Month[row] == 12 and main_data.Day[row] == 25:
if main_data.is_holiday[row] == 0:
main_data.is_holiday[row] = 3 # 3 is label for Xmas
# After filling
print(main_data.loc["25 December, 2012"].is_holiday)
2012-12-25 00:00:00 3
2012-12-25 01:00:00 3
2012-12-25 02:00:00 3
2012-12-25 03:00:00 3
.
.
.
2012-12-25 19:00:00 3
2012-12-25 20:00:00 3
2012-12-25 21:00:00 3
2012-12-25 22:00:00 3
2012-12-25 23:00:00 3
Name: is_holiday, dtype: int64
但是,如果我将同一代码再执行一年(例如2013年),则值将保持不变。我尝试修改代码,包括较小的更改,但假日标签不会更改:
# Before filling
print(main_data.loc["25 December, 2013"].is_holiday)
date_time
2013-12-25 00:00:00 3
2013-12-25 01:00:00 0
2013-12-25 02:00:00 0
2013-12-25 03:00:00 0
.
.
.
2013-12-25 19:00:00 0
2013-12-25 20:00:00 0
2013-12-25 21:00:00 0
2013-12-25 22:00:00 0
2013-12-25 23:00:00 0
Name: is_holiday, dtype: int64
# Manually fill
for row_2 in range(len(main_data.loc["2013"])):
if main_data.Month[row_2] == 12 and main_data.Day[row_2] == 25:
if main_data.is_holiday[row_2] == 0:
main_data.is_holiday[row_2] = 3 # 3 is label for Xmas
# After filling
print(main_data.loc["25 December, 2013"].is_holiday)
2013-12-25 00:00:00 3
2013-12-25 01:00:00 0
2013-12-25 02:00:00 0
2013-12-25 03:00:00 0
.
.
.
2013-12-25 19:00:00 0
2013-12-25 20:00:00 0
2013-12-25 21:00:00 0
2013-12-25 22:00:00 0
2013-12-25 23:00:00 0
Name: is_holiday, dtype: int64
我在这里想念什么?我没想到会发生这种情况。对于某些假期,它可以正常工作,而对于其他假期,则不会。 请记住,Month
和Day
是我在main_data
中设计的单独列。
编辑:欢迎使用更好的方法来实现这一目标。
答案 0 :(得分:2)
Pandas具有一些不错的内置函数来完成此类任务。所以你可以做
import numpy as np
main_data.is_holiday.replace(0, np.nan, inplace=True)
main_data.is_holiday.fillna(method='ffill', inplace=True)
应该这样做。
编辑:
仅将填充应用于假期:
main_data['is_holiday'] = main_data.is_holiday.resample('D').max()
main_data.is_holiday.fillna(method='ffill', inplace=True)
第一行将is_holiday
列替换为假定存在的午夜时间戳记的当天最大值。第二行填充其他行,现在应该有一个NaN。
答案 1 :(得分:2)
假设日期是我只想做的索引:
df.loc[(df.index.day == 25) & (df.index.month ==12),['is_holiday']] = 3
带有示例的完整代码:
#init data
df = pd.DataFrame( \
[['2012-12-25 19:00:00',0,0], \
['2012-12-25 20:00:00',0,0], \
['2012-12-26 19:00:00',0,0], \
['2012-12-26 20:00:00',0,0], \
['2013-01-25 19:00:00',0,0], \
['2013-01-25 20:00:00',0,0], \
['2013-12-25 19:00:00',0,0], \
['2013-12-25 20:00:00',0,0]])
#set index
df.columns = ['date','is_holiday','some_value']
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date')
#do the search
df.loc[(df.index.day == 25) & (df.index.month ==12),['is_holiday']] = 3
print(df)
结果:
is_holiday value
date
2012-12-25 19:00:00 3 0
2012-12-25 20:00:00 3 0
2012-12-26 19:00:00 0 0
2012-12-26 20:00:00 0 0
2013-01-25 19:00:00 0 0
2013-01-25 20:00:00 0 0
2013-12-25 19:00:00 3 0
2013-12-25 20:00:00 3 0
一些有用的链接:
https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#time-date-components
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.loc.html
Select rows from a DataFrame based on values in a column in pandas
答案 2 :(得分:1)
您实际上在做什么
for row in range(len(main_data.loc["2012"]))
#let's says len(main_data.loc["2012"]) = 100
您选择第0到100行,并将0替换为3。
for row_2 in range(len(main_data.loc["2013"]))
#let's says len(main_data.loc["2013"]) = 50
您选择第0到50行,并将0替换为3。
您正在主数据集中执行此操作,因此这两个代码都将替换数据集的第一行。
您可以使用(伪代码)之类的方法解决该问题:
for row in np.where(years=2013,month==12)
答案 3 :(得分:1)
正如我在评论中建议的那样,您可以使用DataFrame.where或np.where进行分配,但是我认为您的情况中最好的是DataFrame.where:
mask = (main_data.date_time.dt.year == 2012) & (main_data.Month == 12) & (main_data.Day == 25)
main_data[mask].is_holiday = main_data[mask]\
.is_holiday\
.where(~(main_data[mask].is_holiday == 0)), 3)
main_data[mask].is_holiday = np.where(main_data[mask].is_holiday == 0, 3,\
main_data[mask].is_holiday)