我的数据帧大约有100M行(内存为1.4Gb)
鉴于输入:
df.head()
Out[1]:
id term x
0 1 A 3
1 1 B 2
2 2 A 1
3 2 B 1
4 2 F 1
5 2 G 1
6 2 Z 1
7 3 K 1
8 3 M 1
9 3 N 1
10 3 Q 1
11 3 R 1
12 3 Z 1
13 4 F 1
我想检索每个id的第一行索引。例如:
Out[1]:
id first_idx
0 1 0
1 2 2
2 3 7
2 4 13
我目前的做法非常缓慢:
first_row = {}
last_id = None
first_row = None
#iterate over all rows
for idx,r in bow.iterrows():
cid = r['id']
if cid != last_id: #is this an ID we haven't seen before?
first_row[cid] = idx
last_id = cid
任何建议都会有很大的帮助。
答案 0 :(得分:4)
方法#1 使用np.unique
-
idx = np.unique(df.id.values, return_index=1)[1]
要获取每个ID
的最后一个索引,只需使用flipped
版本并从数据框的长度中减去 -
len(df)-np.unique(df.id.values[::-1], return_index=1)[1]-1
id
col进行了排序 方法#2-A 我们可以使用slicing
来显着提升性能,因为我们会避免排序 -
a = df.id.values
idx = np.concatenate(([0],np.flatnonzero(a[1:] != a[:-1])+1))
方法#2-B 使用masking
(对于大量身份证号码更好)
a = df.id.values
mask = np.concatenate(([True],a[1:] != a[:-1]))
idx = np.flatnonzero(mask)
对于最后一个索引:
np.flatnonzero(np.concatenate((a[1:] != a[:-1],[True])))
方法#3 对于序列号,我们可以使用np.bincount
-
a = df.id.values
idx = np.bincount(a).cumsum()[:-1]
示例运行 -
In [334]: df
Out[334]:
id term x
0 1 A 3
1 1 B 2
2 2 A 1
3 2 B 1
4 2 F 1
5 2 G 1
6 2 Z 1
7 3 K 1
8 3 M 1
9 3 N 1
10 3 Q 1
11 3 R 1
12 3 Z 1
13 4 F 1
In [335]: idx = np.unique(df.id.values, return_index=1)[1]
In [336]: idx
Out[336]: array([ 0, 2, 7, 13])
如果您需要数据框中的输出 -
In [337]: a = df.id.values
In [338]: pd.DataFrame(np.column_stack((a[idx], idx)), columns=[['id','first_idx']])
Out[338]:
id first_idx
0 1 0
1 2 2
2 3 7
3 4 13
答案 1 :(得分:2)
df = df.index.to_series().groupby(df['id']).first().reset_index(name='x')
print (df)
id x
0 1 0
1 2 2
2 3 7
3 4 13
如果还想要最后的索引值:
df = df.index.to_series().groupby(df['id']).agg(['first','last']).reset_index()
print (df)
id first last
0 1 0 1
1 2 2 6
2 3 7 12
3 4 13 13
答案 2 :(得分:1)
为了完整起见:
last
df.reset_index().groupby("id")["index"].last()
id
1 1
2 6
3 12
4 13
:
df.drop_duplicates('id').reset_index()
1.64 ms ± 31.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
df.reset_index().groupby("id")["index"].first()
1.93 ms ± 8.08 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
df.groupby('id', as_index=False)['x'].agg(lambda x: x.index[0])
7.96 ms ± 419 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
df.index.to_series().groupby(df['id']).first().reset_index(name='x')
3.11 ms ± 77.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
定时:
{{1}}
答案 3 :(得分:1)
... HEAD
drop_duplicates