Pandas Timedelta多个If条件

hsvhsicv  于 2023-04-04  发布在  其他
关注(0)|答案(3)|浏览(133)

我想创建一个名为time_of_day的新列,用于下面的 Dataframe ,以便06-12:59是上午,13-17:59是下午,18-22:59是晚上,其余时间是晚上。
| 身份证|时间|
| --------------|--------------|
| 二十五|00:01|
| 二十五|02:01|
| 二十五|六点五十五分|
| 十八岁|二十二点零三分|
| 十八岁|二十三点三十三分|
| 十八岁|00:33|
"我所期待的"
| 身份证|时间|一天的时间|
| --------------|--------------|--------------|
| 二十五|00:01|夜|
| 二十五|02:01|夜|
| 二十五|六点五十五分|早上好|
| 十八岁|二十二点零三分|晚上|
| 十八岁|二十三点三十三分|夜|
| 十八岁|00:33|夜|
我尝试了numpy矢量化,选择和条件,但失败了。然后我尝试了以下操作:

def conditions(s):
   if (pd.to_timedelta(df['TIME']) >= pd.to_timedelta('06:00:00')) & (pd.to_timedelta(df['TIME']) < pd.to_timedelta('13:00:00')):
       return "Morning" 
   elif (pd.to_timedelta(df['TIME']) >= pd.to_timedelta('13:00:00')) & (pd.to_timedelta(df['TIME']) < pd.to_timedelta('18:00:00')):
       return "Afternoon" 
   elif (pd.to_timedelta(df['TIME']) >= pd.to_timedelta('18:00:00')) & (pd.to_timedelta(df['TIME']) < pd.to_timedelta('23:00:00')):
       return "Evening" 
   elif (pd.to_timedelta(df['TIME']) >= pd.to_timedelta('23:00:00')) & (pd.to_timedelta(df['TIME']) < pd.to_timedelta('06:00:00')):
       return "Night" 
df['TIME_OF_DAY'] = df.apply(conditions, axis=1)
  • 值错误:Series的真值不明确。请使用.empty、.bool()、.item()、.any()或.all()。*

如何解决这个问题?PS:我为enf od each if条件添加了.all(),但仍然得到相同的错误。

4jb9z9bj

4jb9z9bj1#

使用pandas.cut,它将比使用apply的函数更有效:

bins = ['0', '06:00:00', '13:00:00', '18:00:00', '23:00:00', '24:00:00']
labels = ['Night', 'Morning', 'Afternoon', 'Evening', 'Night']

df['TIME_OF_DAY'] = pd.cut(
  pd.to_timedelta(df['TIME']+':00'),
  bins=list(map(pd.Timedelta, bins)),
  labels=labels, right=False, ordered=False
)

输出:

id   TIME TIME_OF_DAY
0  25  00:01       Night
1  25  02:01       Night
2  25  06:55     Morning
3  18  22:03     Evening
4  18  23:33       Night
5  18  00:33       Night

如果你需要一个函数:

def to_day_period(s):
    bins = ['0', '06:00:00', '13:00:00', '18:00:00', '23:00:00', '24:00:00']
    labels = ['Night', 'Morning', 'Afternoon', 'Evening', 'Night']
    
    return pd.cut(
      pd.to_timedelta(s+':00'),
      bins=list(map(pd.Timedelta, bins)),
      labels=labels, right=False, ordered=False
    )

df['TIME_OF_DAY'] = to_day_period(df['TIME'])
lsmepo6l

lsmepo6l2#

假设您在问题中提到的示例DataFrame,您可以进行以下修改以使代码工作:

def conditions(t: pd.Timedelta):
   if pd.Timestamp('06:00:00') <= t < pd.Timestamp('13:00:00'):
       return "Morning" 
   elif pd.Timestamp('13:00:00') <= t < pd.Timestamp('18:00:00'):
       return "Afternoon" 
   elif pd.Timestamp('18:00:00') <= t < pd.Timestamp('23:00:00'):
       return "Evening" 
   else:
       return "Night"

df['TIME_OF_DAY'] = df["TIME"].apply(lambda s: conditions(pd.Timestamp(s)))

输出(df):

id   TIME TIME_OF_DAY
0  25  00:01       Night
1  25  02:01       Night
2  25  06:55     Morning
3  18  22:03     Evening
4  18  23:33       Night
5  18  00:33       Night
woobm2wo

woobm2wo3#

col1=pd.cut(pd.to_datetime(df1.TIME).dt.hour,[6,13,18,23],labels=['morning','afternoon','evening'],right=False).tolist()
df1.assign(TIME_OF_DAY=col1).fillna("night")

输出:

id   TIME TIME_OF_DAY
0  25  00:01       Night
1  25  02:01       Night
2  25  06:55     Morning
3  18  22:03     Evening
4  18  23:33       Night
5  18  00:33       Night

相关问题