数据框如下:
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
对此有快速解决方案吗?
我遗漏了一种情况,其中userID 3可能有更多类型,如3或4.在这种情况下,我想标记has_type_12 = 1为3.我修改了输入和上面所需的输出。
答案 0 :(得分:4)
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
答案 1 :(得分:3)
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
使用双any
的另一种解决方案(如果只有几个类别):
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
答案 2 :(得分:2)
使用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
答案 3 :(得分:0)
使用groupby并为每次使用获取唯一类型ID,然后检查它是否包含{1,2}。
df['has_type_12'] = df.groupby('userid')['type']\
.apply(lambda x: set(x).issuperset({1,2}))\
.astype(int).values[df.userid]