Pandas - 根据行值和行的邻近度生成 ID

Pandas - Generate ID based on row values AND proximity of rows

id dob status sex work_code work_cat gross_income dependent_cat dependent_dob preparer city new_id
1 1981 Married MALE 1111 Government 15000 U 2001 Taxpayer BOSTON 1
2 1981 Married MALE 1111 Government 15000 U 2002 Taxpayer BOSTON 1
3 1983 SINGLE MALE 2222 Federal 20000 N 2009 Taxpayer MIAMI 2
4 1983 SINGLE MALE 2222 Federal 20000 N 2010 Taxpayer MIAMI 2
5 1975 SINGLE MALE 2222 Federal 12000 N/A - Taxpayer NYC 3
6 1983 Married MALE 2222 Federal 18000 U 2013 Taxpayer NYC 4
7 1981 Married MALE 1111 Government 12000 N 2005 Taxpayer PORLAND 5
8 1981 Married MALE 1111 Government 15000 N/A - Taxpayer BOSTON 6

关于数据

我有一个 160 万行的 .txt 数据集,看起来像这样,没有我想要生成的 new_id 列。每行是一个纳税人及其家属(除非 dependent_cat 是 N/A)。当一行后面跟着一个相同的行(没有两个 dependent_X 列)时,假设这实际上是同一家庭,但家庭中有不同的受抚养人(因此,我希望生成 new_id = 1,所以我稍后可以折叠数据集,使每一行都是一个家庭,并且有一列计算家属等等)。

我做了什么

我实际上已经在真实数据集中生成了家庭 ID,但我没有设法合并 'row proximity'。事实证明它非常重要 - 有太多案例,例如 #1、2、8 在不应该聚集在同一个家庭中的例子。由于这个原因,有太多收入为 0 且受抚养人数超过 10 人的家庭。

我的建议

我试着想通了这个问题,然后想到:

遍历每一行, 如果 dependent_cat 是 N/A,分配一个新 ID, 否则,验证前一行在所有列中是否相同(dependent_cat 和 dependent_dob 除外) 如果是这样,请复制其 new_id 否则,new_id = 最后分配的 id +1

为什么我的提议很糟糕 - 寻找替代方案

但是我知道循环遍历 1.6m 数据帧行不是很 pythonic。我可能会尝试,但依赖它会继续我对 Python.

的懒惰方法

散列有什么方法可以帮助我吗?我只发现哈希会使 id #1 和 id #8 最终得到相同的 new_id - 让我处于当前状态。当它传递 id #2 时,我需要散列到 'reset',这样它就不会为 id #8 分配相同的 new_id。我也更愿意,但不要求,new_id 是我所展示的基数(这样 max new_id 最后是我数据集中的家庭数量)。

相关问题:Pandas - Generate Unique ID based on row values

(i) 从与识别家庭相关的列名称创建一个列表(基本上,删除“id”、“dependent_dob”,因为每个条目一个是唯一的,另一个是个人信息受抚养人)。

(ii) 使用 shift 将索引移动 1 并查看连续行是否与 (i) 中标识的列匹配。这个想法是,如果有任何不同,那就是不同的家庭;否则同一户人家。这将创建一个布尔系列。

(iii) 在 (ii) 的结果上使用 cumsum 并将结果分配给 'new_id' 列。

dep_id_cols = ['dob', 'status', 'sex', 'work_code', 'work_cat', 
               'gross_income', 'dependent_cat', 'preparer', 'city']
df['new_id'] = df[dep_id_cols].ne(df[dep_id_cols].shift()).any(axis=1).cumsum()

输出:

   id   dob   status   sex  work_code    work_cat  gross_income dependent_cat  \
0   1  1981  Married  MALE       1111  Government         15000             U   
1   2  1981  Married  MALE       1111  Government         15000             U   
2   3  1983   SINGLE  MALE       2222     Federal         20000             N   
3   4  1983   SINGLE  MALE       2222     Federal         20000             N   
4   5  1975   SINGLE  MALE       2222     Federal         12000           NaN   
5   6  1983  Married  MALE       2222     Federal         18000             U   
6   7  1981  Married  MALE       1111  Government         12000             N   
7   8  1981  Married  MALE       1111  Government         15000           NaN   

  dependent_dob  preparer     city  new_id  
0          2001  Taxpayer   BOSTON       1  
1          2002  Taxpayer   BOSTON       1  
2          2009  Taxpayer    MIAMI       2  
3          2010  Taxpayer    MIAMI       2  
4             -  Taxpayer      NYC       3  
5          2013  Taxpayer      NYC       4  
6          2005  Taxpayer  PORLAND       5  
7             -  Taxpayer   BOSTON       6