簡體   English   中英

檢查一個 dataframe 列是否是另一列的子集

[英]Checking if one dataframe column is a subset of another column

我有一個 dataframe 列Enrolled_MonthsEligible_Months ,描述如下:

month_list1 = [
    [(1, 2018), (2, 2018), (3, 2019)],
    [(7, 2018), (8, 2018), (10, 2018)],
    [(4, 2018), (5, 2018), (7, 2018)],
    [(1, 2019), (2, 2019), (4, 2019)]
]

month_list2 = [
    [(2, 2018), (3, 2019)],
    [(7, 2018), (8, 2018)],
    [(2, 2018), (3, 2019)],
    [(10, 2018), (11, 2019)]
]

EID = [1, 2, 3, 4]

df = pd.DataFrame({
    'EID': EID,
    'Enrolled_Months': month_list1,
    'Eligible_Months': month_list2
})
df

Out[6]: 
   EID                     Enrolled_Months           Eligible_Months
0    1   [(1, 2018), (2, 2018), (3, 2019)]    [(2, 2018), (3, 2019)]
1    2  [(7, 2018), (8, 2018), (10, 2018)]    [(7, 2018), (8, 2018)]
2    3   [(4, 2018), (5, 2018), (7, 2018)]    [(2, 2018), (3, 2019)]
3    4   [(1, 2019), (2, 2019), (4, 2019)]  [(10, 2018), (11, 2019)]

我想創建一個名為Check的新列,如果Enrolled_Months包含Eligible_Months的所有元素,則該列為真。 我想要的 output 如下:

Out[8]: 
   EID                     Enrolled_Months           Eligible_Months  Check
0    1   [(1, 2018), (2, 2018), (3, 2019)]    [(2, 2018), (3, 2019)]   True
1    2  [(7, 2018), (8, 2018), (10, 2018)]    [(7, 2018), (8, 2018)]   True
2    3   [(4, 2018), (5, 2018), (7, 2018)]    [(2, 2018), (3, 2019)]  False
3    4   [(1, 2019), (2, 2019), (4, 2019)]  [(10, 2018), (11, 2019)]  False

我試過以下方法:

df['Check'] = set(df['Eligible_Months']).issubset(df['Enrolled_Months'])

但最終得到錯誤TypeError: unhashable type: 'list'

關於如何實現這一目標的任何想法?

旁注: Enrolled_Months數據最初采用非常不同的格式,每個月都有自己的二進制列,以及一個單獨的Year列指定年份(imo 設計非常糟糕)。 我創建了列表列,因為我認為它更容易使用,但如果原始格式更適合我想要實現的目標,請告訴我。

您可以使用一些explodes然后evalany

df['Check'] = df.explode('Eligible_Months').explode('Enrolled_Months').eval('Enrolled_Months == Eligible_Months').groupby(level=0).any()

Output:

>>> df
   EID                     Enrolled_Months           Eligible_Months  Check
0    1   [(1, 2018), (2, 2018), (3, 2019)]    [(2, 2018), (3, 2019)]   True
1    2  [(7, 2018), (8, 2018), (10, 2018)]    [(7, 2018), (8, 2018)]   True
2    3   [(4, 2018), (5, 2018), (7, 2018)]    [(2, 2018), (3, 2019)]  False
3    4   [(1, 2019), (2, 2019), (4, 2019)]  [(10, 2018), (11, 2019)]  False

您可以使用df.apply()創建新列:

df['Check'] = df.apply(
    lambda row: set(row['Eligible_Months']).issubset(row['Enrolled_Months']), axis=1
)

這輸出:

   EID                     Enrolled_Months           Eligible_Months  Check
0    1   [(1, 2018), (2, 2018), (3, 2019)]    [(2, 2018), (3, 2019)]   True
1    2  [(7, 2018), (8, 2018), (10, 2018)]    [(7, 2018), (8, 2018)]   True
2    3   [(4, 2018), (5, 2018), (7, 2018)]    [(2, 2018), (3, 2019)]  False
3    4   [(1, 2019), (2, 2019), (4, 2019)]  [(10, 2018), (11, 2019)]  False

列表理解工作正常:

df.assign(check = [set(l).issuperset(r) 
                   for l, r in 
                   zip(df.Enrolled_Months, df.Eligible_Months)])

   EID                     Enrolled_Months           Eligible_Months  check
0    1   [(1, 2018), (2, 2018), (3, 2019)]    [(2, 2018), (3, 2019)]   True
1    2  [(7, 2018), (8, 2018), (10, 2018)]    [(7, 2018), (8, 2018)]   True
2    3   [(4, 2018), (5, 2018), (7, 2018)]    [(2, 2018), (3, 2019)]  False
3    4   [(1, 2019), (2, 2019), (4, 2019)]  [(10, 2018), (11, 2019)]  False

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM