[英]Find closest element of a pandas dataframe column in another column's list
[英]find if the value in pandas column is in another column's list
我有一個看起來像這樣的 df:
ID dates holidays
0 ABC 01/01/2022 [12/25/2021, 01/01/2022, 01/17/2022]
1 DEF 03/17/2022 [01/01/2022, 06/01/2022, 27/01/2022]
如果日期列中的值在該 ID 的假期列表中,我需要創建另一個具有 bool 值的列isHoliday
。 我正在嘗試使用下面的代碼,但它顯示錯誤: TypeError: unhashable type: 'list'
:
df['isHoliday'] = np.where(df['dates'].isin(df['holidays']), True, False)
有什么方法可以找到列日期值是否在對應於每個 ID 的列表中?
explode
在這里效果很好:
df['isHoliday'] = df.eval('dates in holidays.explode()')
Output:
>>> df
ID dates holidays isHoliday
0 ABC 01/01/2022 [12/25/2021, 01/01/2022, 01/17/2022] True
1 DEF 03/17/2022 [01/01/2022, 06/01/2022, 27/01/2022] False
基准:
def scott():
[d in l for d, l in zip(df['dates'], df['holidays'])]
def shubham():
pd.DataFrame([*df['holidays']]).eq(df['dates'], axis=0).any(1)
def charles():
df[['dates','holidays']].apply(lambda row: row['dates'] in row['holidays'], axis=1)
def richardec():
df.eval('dates in holidays.explode()')
###
%timeit scott()
# 5.99 µs ± 302 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
%timeit shubham()
# 547 µs ± 10.6 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
%timeit charles()
# 525 µs ± 2.27 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
%timeit richardec()
# 971 µs ± 71.3 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
所以我的是最短的,但斯科特的是最快的!
嘗試這個:
df['isholiday'] = [d in l for d, l in zip(df['dates'], df['holidays'])]
Output:
ID dates holidays isholiday
0 ABC 01/01/2022 [12/25/2021, 01/01/2022, 01/17/2022] True
1 DEF 03/17/2022 [01/01/2022, 06/01/2022, 01/27/2022] False
這是一種矢量化方法:
df['isholiday'] = pd.DataFrame([*df['holidays']]).eq(df['dates'], axis=0).any(1)
結果
ID dates holidays isholiday
0 ABC 01/01/2022 [12/25/2021, 01/01/2022, 01/17/2022] True
1 DEF 03/17/2022 [01/01/2022, 06/01/2022, 27/01/2022] False
問題的根源是.isin()
方法沒有向量化它的參數,所以它檢查每個日期是否在整個列表系列中,並且在這個過程中我相信它為了速度目的將參數轉換為一個集合。 集合只接受不可變的值,而列表是可變的,所以它給出了不可散列的類型錯誤。
我想你會想要使用 apply 代替:
df['isHoliday'] = df[['dates','holidays']].apply(
lambda row: row['dates'] in row['holidays'],
axis=1
)
在這種情況下,您不需要 np.where 因為條件本身會返回一系列True
和False
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.