假设我有一个数据帧:
df = pd.DataFrame({'a':[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3],
'b':[2016, 2017, 2018, 2019, 2000, 2000, 2000, 2000, 2007, 2008, 2014]})
我想按此数据分组,并比较组a
中少于其他组的年数。
在组1中,2016年是第0年,那么2017年是第1年(或之后有1年)。
我试着这样做:
df['c'] = df.groupby('a')['b'].apply(lambda x: [sum(y > x) for y in x]).reset_index(drop=False)
但这需要很长的时间。我想知道有没有更好的方法。我正在处理650万行。
预期输出:
a b c
0 1 2016 0
1 1 2017 1
2 1 2018 2
3 1 2019 3
4 2 2000 0
5 2 2000 0
6 2 2000 0
7 2 2000 0
8 3 2007 0
9 3 2008 1
10 3 2014 2
发布于 2019-04-19 02:31:21
我会使用rank
和之后的sub
1,我认为它非常可读性,大约是其他答案的两倍,大约是原始方法的3.5倍:
df.groupby(['a'])['b'].rank('min').sub(1)
#0 0.0
#1 1.0
#2 2.0
#3 3.0
#4 0.0
#5 0.0
#6 0.0
#7 0.0
#8 0.0
#9 1.0
#10 2.0
%timeit df.groupby(['a'])['b'].rank('min').sub(1)
#1.58 ms ± 61.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit df.groupby('a')['b'].transform(lambda x: pd.factorize(x)[0])
#3.76 ms ± 330 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit df.groupby('a')['b'].apply(lambda x: [sum(y > x) for y in x]).reset_index(drop=False)
#5.32 ms ± 129 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
发布于 2019-04-19 15:39:27
干净高效的解决方案:
import pandas as pd
df = pd.DataFrame({'a':[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3],
'b':[2016, 2017, 2018, 2019, 2000, 2000, 2000, 2000, 2007, 2008, 2014]})
df=df.set_index('a')
df=df.sort_index()
quickmap={}
for index in df.index.unique():
temphash={}
val=0
for i in df.loc[index]['b'].unique():
temphash[i]=val
val+=1
quickmap[index]=temphash
df=df.reset_index()
def toret(row):
key=row['a']
subkey=row['b']
return quickmap[key][subkey]
df['c']=df.apply(toret,axis=1)
https://stackoverflow.com/questions/55751785
复制相似问题