问题描述
我有基于三列分配唯一标识符的数据框,即 [col2,col3,col3]
数据框 1:
col1 col2 col3 col4 col5 unique_id
1 abc bcv zxc www.com 8
2 bcd qwe rty www.@com 12
3 klp oiu ytr www.io 15
4 zxc qwe rty www.com 6
数据预处理后,将导入Dataframe_2,列值与上图相同,但没有unique_id。 Dataframe_2 行必须根据 col2、col3、col4 并参考 Dataframe1 分配唯一标识符。
如果 Dataframe_2 有 Dataframe1 中不存在的新行,则分配新的标识符。
数据框_2:
col1 col2 col3 col4 col5
1 bcd qwe rty www.@com
2 zxc qwe rty www.com
3 abc bcv zxc www.com
4 kph hir mat www.com
预期数据帧_2:
col1 col2 col3 col4 col5 unique_id
1 bcd qwe rty www.@com 12
2 zxc qwe rty www.com 6
3 abc bcv zxc www.com 8
4 kph hir mat www.com 35
由于 Row4 不存在于 Dataframe1 中,因此分配了一个新的唯一标识符。
解决方法
# assign the old unique_id
df2n = df2.join(df1.set_index(['col2','col3','col4','col5'])[['unique_id']],on=['col2','col5'],how='left')
# assign new unique_id with max df1.unique_id + 1
id_max = df1.unique_id.max() + 1
null_num = df2n['unique_id'].isnull().sum()
cond = df2n['unique_id'].isnull()
df2n.loc[cond,'unique_id'] = range(id_max,id_max + null_num)
df2n['unique_id'] = df2n['unique_id'].astype(int)
print(df2n)
col1 col2 col3 col4 col5 unique_id
0 1 bcd qwe rty www.@com 12
1 2 zxc qwe rty www.com 6
2 3 abc bcv zxc www.com 8
3 4 kph hir mat www.com 16
,
首先通过DataFrame.merge
添加列unique_id
,对于子集中指定的列on
进行合并,忽略左连接['col2','col4']
参数。对于不匹配的值会创建缺失值,因此使用 Series.isna
来测试它们,np.arange
用于在最大值之后创建新数组并在 DataFrame.loc
df = Dataframe_2.merge(Dataframe_1[['col2','unique_id']],how='left')
mask = df['unique_id'].isna()
maximal = Dataframe_1['unique_id'].max() + 1
df.loc[mask,'unique_id'] = np.arange(maximal,maximal + mask.sum())
df['unique_id'] = df['unique_id'].astype(int)
print (df)
col1 col2 col3 col4 col5 unique_id
0 1 bcd qwe rty www.@com 12
1 2 zxc qwe rty www.com 6
2 3 abc bcv zxc www.com 8
3 4 kph hir mat www.com 16
,
import math
import random
import pandas as pd
import numpy as np
df3 = pd.merge(df1,df2,'col4'],how='right')
def return_unique_num(df1):
uniqueIds = list(df1['unique_id'].values)
unique_num = random.randint(1,len(df1)+1)
while True:
if unique_num in uniqueIds:
unique_num = random.randint(1,len(df1)+1)
else:
break
return unique_num
for i,e in enumerate(df3['unique_id']):
if math.isnan(e):
df3.iloc[i,5] = return_unique_num(df1) #replace nan value with unique integer in df3 unique_id column
df3['unique_id'] = df3['unique_id'].astype(int)
df2['unique_id'] = df3['unique_id']
它将根据 df1 的 unique_id 为 df2 分配唯一 ID
输出
col1 col2 col3 col4 col5 unique_id
1 bcd qwe rty www.@com 12
2 zxc qwe rty www.com 6
3 abc bcv zxc www.com 8
4 kph hir mat www.com 35