我有一个数据帧,我想在其中基于另外两列创建一个新列。 这是我的数据帧的样子:
HOUSEID PERSONID
20000017 1
20000017 1
20000017 2
20000017 3
20000017 3
20000231 1
20000231 1
20000231 2
20000521 1
20000521 2
20000521 2
20001283 1
20001283 2
20001283 3
20001283 3
我需要在新列中按顺序定义一个数字,用于"HOUSEID"和"PERSONID"的唯一组合,标有"PERSON_COUNTER"。 每当有一个新的组合时,它就会上升一个数字,并将其放在从 1 开始的组合前面。 这是我的意思:
HOUSEID PERSONID PERSON_COUNTER
20000017 1 1
20000017 1 1
20000017 2 2
20000017 3 3
20000017 3 3
20000231 1 4
20000231 1 4
20000231 2 5
20000521 1 6
20000521 2 7
20000521 2 7
20001283 1 8
20001283 2 9
20001283 3 10
20001283 3 10
我已经尝试了下面的代码,它运行良好,但由于我有一个相对较大的数据帧(大约 100 万行(,因此执行大约需要 2 个小时:
df.insert(2, 'PERSON_COUNTER', '')
list_person_counter = []
def person_counter(houseid, personid):
if [houseid, personid] in list_person_counter:
return len(list_person_counter)
else:
list_person_counter.append([houseid, personid])
return len(list_person_counter)
df['PERSON_COUNTER'] = df.apply(lambda row: person_counter(row['HOUSEID'], row['PERSONID']), axis=1)
如果有人能提供最快的方法,我将不胜感激。
谢谢
按DataFrame.ne
比较具有DataFrame.shift
ed 值的!=
的选定列,然后按DataFrame.any
测试每行至少一个True
,最后添加累积总和Series.cumsum
:
c = ['PERSONID', 'HOUSEID']
df['PERSON_COUNTER'] = df[c].ne(df[c].shift()).any(axis=1).cumsum()
print (df)
HOUSEID PERSONID PERSON_COUNTER
0 20000017 1 1
1 20000017 1 1
2 20000017 2 2
3 20000017 3 3
4 20000017 3 3
5 20000231 1 4
6 20000231 1 4
7 20000231 2 5
8 20000521 1 6
9 20000521 2 7
10 20000521 2 7
11 20001283 1 8
12 20001283 2 9
13 20001283 3 10
14 20001283 3 10
如果只想按一列工作:
df['PERSON_COUNTER'] = df['PERSONID'].ne(df['PERSONID'].shift()).cumsum()