添加一个“flag”列,说明一个ID在另一列中是否有某些值

2024-09-27 09:37:46 发布

您现在位置:Python中文网/ 问答频道 /正文

数据帧类似于:

 In [1]: df
 Out[2]:
          userid type
    0      1       1
    1      1       2
    2      2       1
    3      3       1
    4      3       2
    5      3       3    

现在我想在其中添加一个关于userid是否在“type”列中有特定值的列(比如type1和type2)。 这就是我想要的输出:

 In [1]: df
 Out[2]:
          userid type  has_type_12
    0      1       1      1
    1      1       2      1
    2      2       1      0
    3      3       1      1
    4      3       2      1
    5      3       3      1

有什么快速的解决办法吗?你知道吗


我遗漏了一种情况,userid3可能有更多类型,比如3或4。在这种情况下,我想为3标记has\u type\u 12=1。我已经修改了上面的输入和期望的输出。你知道吗


Tags: 数据in标记类型dftype情况out
3条回答

^{}+^{}set一起使用:

cats = [1,2]
df['has_type_12'] = df.groupby('userid')['type'] \
                      .transform(lambda x: set(x) >= set((cats))) \
                      .astype(int) 
print (df)
   userid  type  has_type_12
0       1     1            1
1       1     2            1
2       2     1            0
3       3     1            1
4       3     2            1
5       3     3            1

另一个具有双^{}(如果只有几个类别)的解决方案:

cats = [1,2]
df['has_type_12'] = df.groupby('userid')['type'] \
                      .transform(lambda x: ((x == 1).any()) & ((x == 2).any())) \
                      .astype(int) 
print (df)
   userid  type  has_type_12
0       1     1            1
1       1     2            1
2       2     1            0
3       3     1            1
4       3     2            1
5       3     3            1

当使用set时,>=操作符测试右手侧是否是左手侧的子集。我使用ge方法作为>=的代理

使用groupby

m = df.groupby('userid').type.apply(set)
df.assign(
  has_type_12=df.userid.map(m).ge({1, 2}).astype(int)
)

   userid  type  has_type_12
0       1     1            1
1       1     2            1
2       2     1            0
3       3     1            1
4       3     2            1
5       3     3            1

使用defaultdict

from collections import defaultdict

d = defaultdict(set)
[d[k].add(v) for k, v in zip(df.userid.values.tolist(), df.type.values.tolist())];
df.assign(has_type_12=df.userid.map(d).ge({1, 2}).astype(int))

   userid  type  has_type_12
0       1     1            1
1       1     2            1
2       2     1            0
3       3     1            1
4       3     2            1
5       3     3            1

时间安排 大数据

np.random.seed([3,1415])
df = pd.DataFrame(dict(
        userid=np.random.randint(1000, size=100000),
        type=np.random.randint(100, size=100000)
    ))

%%timeit
d = defaultdict(set)
[d[k].add(v) for k, v in zip(df.userid.values.tolist(), df.type.values.tolist())];
df.userid.map(d).ge({1, 2}).astype(int)
10 loops, best of 3: 55.6 ms per loop

%%timeit 
m = df.groupby('userid').type.apply(set)
df.userid.map(m).ge({1, 2}).astype(int)
10 loops, best of 3: 76.1 ms per loop

%timeit df.groupby('userid')['type'] \
                      .transform(lambda x: set(x) >= set((cats))) \
                      .astype(int)
1 loop, best of 3: 206 ms per loop
In [308]: df['has_type_12'] = \
              df.groupby('userid')['type'].transform(lambda x: x[x.isin([1,2])].nunique() == 2)

In [309]: df
Out[309]:
   userid  type  has_type_12
0       1     1            1
1       1     2            1
2       2     1            0
3       3     1            1
4       3     2            1
5       3     3            1

相关问题 更多 >

    热门问题