我有以下示例代码:
data = ['05/21/2021','05/21/2022','05/21/2023']
df = pd.DataFrame(data, columns=['register_date'])
df['register_year'] = pd.to_datetime(df['register_date']).dt.year
df['study_year'] = 2022
这里,我有一个 Dataframe ,看起来像这样:
| 登记日期|登记年|学习年|
| - ------|- ------|- ------|
| 2019 - 05 - 21 2019 - 05 - 21|小行星2021|小行星2022|
| 2019 - 05 - 21 10:00:00|小行星2022|小行星2022|
| 2019 - 05 - 21 10:00:00|二○二三|小行星2022|
目标是创建另一个名为“duration_start”的列,其中如果register_year < study_year
,则为1
;如果register_year > study_year
,则为0
;如果register_year == study_year
,则为register_year的年末与注册日期之间的年份比例。
我创建了以下条件,以便与np.select()一起使用
register_year_lt_study_year = df['register_year'] < df['study_year']
register_year_gt_study_year = df['Register_year'] > df['Study_year']
和一个函数,它计算从年末开始的一年的比例:
def proportion_to_year_end(date):
start = pd.to_datetime(date)
year_end = pd.to_datetime('12/31/' + str(start.year))
return (year_end - start).days/365
然而,我不确定应该如何填写??
,因为proportion_to_year_end()是一个接受字符串的单值函数,但np.select()接受相同长度的列。df['duration_start'] = np.select([register_year_lt_study_year, register_year_gt_study_year], [1, 0], ??)
我考虑过使用apply()
函数,也许可以生成另一列,然后删除它,但这需要更多的逻辑来首先处理0和1,然后在此之上,应用proportion_to_year_end,然后删除临时列。
或者,我考虑过将proportion_to_year_end()改为两列,但我不确定如何在没有for循环的情况下编写它,这是我们应该避免的。
我想知道是否有更好的方法来解决这类问题,其中单值函数和 Dataframe 中的列之间存在明显的维度不匹配?
1条答案
按热度按时间osh3o9ms1#
np.select
的文档表明默认值必须是一个值,所以我认为你不能在那里应用你的函数。你可以做的一件事是用1 s和0 s部分填充数组,给予数组的其余部分(其中
register_year == study_year
)一个特定的值,比如nan或-1,并通过掩码填充该部分。例如:我不得不在这里使用
vectorize
,但如果您更改proportion_to_year_end
以支持datetime数组,我们可以删除它。