如何检查数据框列值是否出现在数据框列中的所有唯一年份

问题描述

df1 = pd.DataFrame({'type': ['cst1','cst1','cst2','cst3','cst3'],'year':[2017,2018,2019,2020,2017,2020]})

   type  year
0   cst1  2017
1   cst1  2018
2   cst1  2019
3   cst1  2020
4   cst2  2018
5   cst2  2019
6   cst2  2020
7   cst3  2017
8   cst3  2018
9   cst3  2019
10  cst3  2020

对于上述数据框需要检查每个类型值是否存在于所有四年 [2017,2020] 需要标记为 1,否则为 0。 例如:第一种类型 cst1 出现在所有 4 年中,因此标记为 1,cst2 仅出现在 3 年中,因此标记为 1。 注意:理想情况下,只包含四年,即 2017 - 2020。类型和年份组合将是唯一的。

期望输出

type  year label
0   cst1  2017     1
1   cst1  2018     1
2   cst1  2019     1
3   cst1  2020     1
4   cst2  2018     0
5   cst2  2019     0
6   cst2  2020     0
7   cst3  2017     1
8   cst3  2018     1
9   cst3  2019     1
10  cst3  2020     1

解决方法

如果所有年份都在 2017 年 -2020 年的范围内,我想 groupby/transform with nunique 可以:

df['label'] = (df1.groupby('type').transform('nunique') == 4).astype(int)

替代方案:

df1['label'] = 0 
def test(x):
    return set(x.values) == {2017,2018,2019,2020}
df1.iloc[df1.groupby('type')['year'].filter(test).index,2] = 1
,
  • 使用groupby()
  • 根据类型创建组
  • 使用 transform()
  • 根据组获取每行中的年元组
  • 将这些元组与您所需的年份进行比较。它将为每一行结果 True/False
  • 使用 astype('int')
  • 将布尔值 (True/False) 转换为整数 (1/0)
required = (2017,2020)
df1["label"] = (df1.groupby('type').transform(tuple)["year"] == required).astype('int')

print(df1)

    type    year    label
0   cst1    2017    1
1   cst1    2018    1
2   cst1    2019    1
3   cst1    2020    1
4   cst2    2018    0
5   cst2    2019    0
6   cst2    2020    0
7   cst3    2017    1
8   cst3    2018    1
9   cst3    2019    1
10  cst3    2020    1
,

让我们试试:

  1. 一个 groupby transform 用于测试每个组的年份是否是所需年份的子集。
  2. 使用 astype(int) 将布尔值转换为 1 和 0
import pandas as pd

df1 = pd.DataFrame({'type': ['cst1','cst1','cst2','cst3','cst3'],'year': [2017,2020,2017,2020]})

years = {2017,2020}

df1['label'] = (
    df1.groupby('type').year.transform(lambda x: years.issubset(x))
).astype(int)
print(df1)

df1

    type  year  label
0   cst1  2017      1
1   cst1  2018      1
2   cst1  2019      1
3   cst1  2020      1
4   cst2  2018      0
5   cst2  2019      0
6   cst2  2020      0
7   cst3  2017      1
8   cst3  2018      1
9   cst3  2019      1
10  cst3  2020      1

*注意这将匹配至少四年的任何组。因此,如果一个组包含来自 [2016,2020] 的条目,它将被匹配。