我有下表
date ui mw maxw tC HL msurp
01/03/2004 A 10 10 eC 0.25 0.1
01/04/2004 A 10 10 eC 0.25 -0.1
01/03/2004 B 20 20 bC 0.5 0.3
01/03/2004 B 20 20 bC 0.25 0.3
我要做的是在此表中添加一列,基本上列举了ui,mw,maxw,tC和HL的唯一组合并枚举
所以例如在上表中
ui,mw,maxw,tC和HL的唯一组合是
A,10, 10, eC, 0.25
B,20, 20, bC, 0.5
B,20, 20, bC, 0.5
共有3个,所以输出应该是
date ui mw maxw tC HL msurp counter
01/03/2004 A 10 10 eC 0.25 0.1 1
01/04/2004 A 10 10 eC 0.25 -0.1 1
01/03/2004 B 20 20 bC 0.5 0.3 2
01/03/2004 B 20 20 bC 0.25 0.3 3
答案 0 :(得分:9)
选项1
pd.Series.factorize
df.assign(
counter=df[['ui', 'mw', 'maxw', 'tC', 'HL']].apply(tuple, 1).factorize()[0] + 1)
date ui mw maxw tC HL msurp counter
0 01/03/2004 A 10 10 eC 0.25 0.1 1
1 01/04/2004 A 10 10 eC 0.25 -0.1 1
2 01/03/2004 B 20 20 bC 0.50 0.3 2
3 01/03/2004 B 20 20 bC 0.25 0.3 3
选项1.5
选项1更令人讨厌的版本,但应该更快
df.assign(
counter=pd.factorize(list(zip(
*[df[c].values.tolist() for c in ['ui', 'mw', 'maxw', 'tC', 'HL']]
)))[0] + 1
)
date ui mw maxw tC HL msurp counter
0 01/03/2004 A 10 10 eC 0.25 0.1 1
1 01/04/2004 A 10 10 eC 0.25 -0.1 1
2 01/03/2004 B 20 20 bC 0.50 0.3 2
3 01/03/2004 B 20 20 bC 0.25 0.3 3
选项2
@ ayhan的答案(如果他发布,将会删除)
df.assign(
counter=df.groupby(['ui', 'mw', 'maxw', 'tC', 'HL']).ngroup() + 1)
date ui mw maxw tC HL msurp counter
0 01/03/2004 A 10 10 eC 0.25 0.1 1
1 01/04/2004 A 10 10 eC 0.25 -0.1 1
2 01/03/2004 B 20 20 bC 0.50 0.3 3
3 01/03/2004 B 20 20 bC 0.25 0.3 2
<强>时序强>
以下代码
(lambda r: r.div(r.min(1), 0).assign(best=lambda x: x.idxmin(1)))(results)
pir1 pir2 ayhan best
100 17.260639 1.000000 3.438354 pir2
300 30.550010 1.000000 2.598456 pir2
1000 43.201163 1.000000 1.236190 pir2
3000 61.593932 1.000000 1.025420 pir2
10000 127.003138 2.177171 1.000000 ayhan
pir1 = lambda d: d.assign(counter=d[['ui', 'mw', 'maxw', 'tC', 'HL']].apply(tuple, 1).factorize()[0] + 1)
pir2 = lambda d: d.assign(counter=pd.factorize(list(zip(*[d[c].values.tolist() for c in ['ui', 'mw', 'maxw', 'tC', 'HL']])))[0] + 1)
ayhan = lambda d: d.assign(counter=d.groupby(['ui', 'mw', 'maxw', 'tC', 'HL']).ngroup() + 1)
results = pd.DataFrame(
index=[100, 300, 1000, 3000, 10000],
columns='pir1 pir2 ayhan'.split(),
dtype=float
)
for i in results.index:
d = pd.concat([df] * i, ignore_index=True)
for j in results.columns:
stmt = '{}(d)'.format(j)
setp = 'from __main__ import d, {}'.format(j)
results.set_value(i, j, timeit(stmt, setp, number=10))
results.plot(loglog=True)
答案 1 :(得分:2)
像ayhan的回答一样,假设顺序并不重要
df[['ui','mw','maxw','tC','HL']].T.apply(lambda x : ','.join(x.astype(str))).astype('category').cat.codes
Out[1247]:
0 0
1 0
2 2
3 1
dtype: int8
正如你所说我可以通过这个聚合而不是通过[ui,mw,maxw等
指定分组只需执行此操作,然后groupby('counter')
df['counter']=df[['ui','mw','maxw','tC','HL']].T.apply(lambda x : ','.join(x.astype(str)))