在python中有一个数据框:
CASE TYPE
1 A
1 A
1 A
2 A
2 B
3 B
3 B
3 B
如何创建一个结果数据框,它可以产生所有情况,并且可以产生" A"如果案件只有" A'"分配," B"如果它只是" B'"或"混合"如果案件既有A又有B?
结果将是:
Case Type
1 A
2 MIXED
3 B
答案 0 :(得分:2)
这是一个选项,我们首先按CASE
组收集TYPE作为列表,然后检查唯一TYPE的length
,如果它大于1
,则返回{ {1}}否则TYPE本身:
MIXED
答案 1 :(得分:2)
df['NTYPES'] = df.groupby('CASE').transform(lambda x: x.nunique())
df.loc[df.NTYPES > 1, 'TYPE'] = 'MIXED'
df.groupby('TYPE', as_index=False).first().drop('NTYPES', 1)
TYPE CASE
0 A 1
1 B 3
2 MIXED 2
答案 2 :(得分:1)
这有点难看,但不是那么缓慢的解决方案:
In [154]: df
Out[154]:
CASE TYPE
0 1 A
1 1 A
2 1 A
3 2 A
4 2 B
5 3 B
6 3 B
7 3 B
8 4 C
9 4 C
10 4 B
In [155]: %paste
(df.groupby('CASE')['TYPE']
.apply(lambda x: x.head(1) if x.nunique() == 1 else pd.Series(['MIX']))
.reset_index()
.drop('level_1', 1)
)
## -- End pasted text --
Out[155]:
CASE TYPE
0 1 A
1 2 MIX
2 3 B
3 4 MIX
时间:对800K行DF:
In [191]: df = pd.concat([df] * 10**5, ignore_index=True)
In [192]: df.shape
Out[192]: (800000, 3)
In [193]: %timeit Psidom(df)
1 loop, best of 3: 235 ms per loop
In [194]: %timeit capitalistpug(df)
1 loop, best of 3: 419 ms per loop
In [195]: %timeit Alberto_Garcia_Raboso(df)
10 loops, best of 3: 112 ms per loop
In [196]: %timeit MaxU(df)
10 loops, best of 3: 80.4 ms per loop
答案 3 :(得分:1)
这是一个(公认的过度设计)解决方案,可避免循环群组和DataFrame.apply
(这些很慢,因此如果数据集足够大,避免它们可能会变得很重要。)
import pandas as pd
df = pd.DataFrame({'CASE': [1]*3 + [2]*2 + [3]*3,
'TYPE': ['A']*4 + ['B']*4})
我们按CASE
分组并计算TYPE
A
或B
的相对频率:
grouped = df.groupby('CASE')
vc = (grouped['TYPE'].value_counts(normalize=True)
.unstack(level=0)
.fillna(0))
这是vc
的样子
CASE 1 2 3
TYPE
A 1.0 0.5 0.0
B 0.0 0.5 0.0
请注意,所有信息都包含在第一行中。将所述行切换为具有pd.cut
的区域,可得到所需的结果:
tolerance = 1e-10
bins = [-tolerance, tolerance, 1-tolerance, 1+tolerance]
types = pd.cut(vc.loc['A'], bins=bins, labels=['B', 'MIXED', 'A'])
我们得到:
CASE
1 A
2 MIXED
3 B
Name: A, dtype: category
Categories (3, object): [B < MIXED < A]
为了更好地衡量,我们可以重命名types
系列:
types.name = 'TYPE'