Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 基于名称从多个数据帧生成唯一密钥_Python_Pandas_Dataframe - Fatal编程技术网

Python 基于名称从多个数据帧生成唯一密钥

Python 基于名称从多个数据帧生成唯一密钥,python,pandas,dataframe,Python,Pandas,Dataframe,我有两个数据帧。正如您所看到的,函数正确地合并了它,但它是错误的。因为carid必须是唯一的,并且不能分配两次。我怎样才能解决这个问题?它可以在一个数据帧中出现多次,但在两个数据记录中必须保持唯一。因此,在所有数据记录中,Carid=1=Mercedes-benz,而不是Carid=1=Mercedes-benz&Citroen import pandas as pd d = {'Carid ': [1, 2, 3, 1], 'Carname': ['Mercedes-Benz', 'Audi

我有两个数据帧。正如您所看到的,函数正确地合并了它,但它是错误的。因为carid必须是唯一的,并且不能分配两次。我怎样才能解决这个问题?它可以在一个数据帧中出现多次,但在两个数据记录中必须保持唯一。因此,在所有数据记录中,
Carid=1=Mercedes-benz
,而不是
Carid=1=Mercedes-benz&Citroen

import pandas as pd

d = {'Carid ': [1, 2, 3, 1], 'Carname': ['Mercedes-Benz', 'Audi', 'BMW', 'Mercedes-Benz'], 'model': ['S-Klasse AMG 63s', 'S6', 'X6 M-Power', 'Maybach']}
df = pd.DataFrame(data=d)
display(df.head())

我想要什么


一种可能的方法是在合并之前进行一些数据处理

你可以考虑通过较小的数据文件,看看代码< CARID的值是什么冲突。然后为这些应用新的唯一值

我想到了这一点,但是可以对其进行大量优化:

d2 = {'Carid': [1, 2, 3, 1], 'Carname': ['Mercedes-Benz', 'Audi', 'BMW', 'Mercedes-Benz'], 'model': ['S-Klasse AMG 63s', 'S6', 'X6 M-Power', 'Maybach']}
df2 = pd.DataFrame(data=d2)

d = {'Carid': [0,1,2],'Carname': ['VW','Citroen','Opel'],'Model':['GTI','S','Corsa']}
df = pd.DataFrame(data=d)

#We loop through the bigger dataframe index values
for indx in df2.index:
    #We fetch all the ids that are present in the df
    ids = list(df2['Carid'].values)
    
    #We need this to make sure our loop doesn't break from the index size difference
    try:
        #The row we want to modify
        new_row = df.loc[indx]
        #The id it currently has
        old_id = df.Carid[indx]
        
        #Check if the id is already present 
        if old_id in ids:
            #If it is, we take the highest id out of the present ones and up it by one
            top_id = max(ids)
            new_id = top_id+1
            
            #Add it to the existing ids
            ids.append(new_id)
            
            #Set the new value
            df.Carid[indx] = new_id
        elif old_id not in ids:
            pass
        
    except KeyError as e:
        print("Index out of range")
注意,我确实将列名从
Carid
更改为
Carid

完成此操作后,所有车辆都应该有unqiue ID,这意味着您可以使用concat合并两个数据帧。

Method 1 如果您不介意将键更改为浮动,第一种方法是使用
cumcount

df3 = pd.concat([df,df2])

s = df3.groupby('Carname',sort=False)['Carid'].first().to_frame()
s['Carid'] = s['Carid']  + s.groupby('Carid').cumcount() / 10

new_ids = s.to_dict(orient='dict')['Carid']

df3['Carid'] = df3['Carname'].map(new_ids)

  Carid        Carname             model
0    1.0  Mercedes-Benz  S-Klasse AMG 63s
1    2.0           Audi                S6
2    3.0            BMW        X6 M-Power
3    1.0  Mercedes-Benz           Maybach
0    4.0             VW               GTI
1    1.1        Citroen                 S
2    5.0           Opel             Corsa
方法2使用字典的功能性方法。 假设。 函数的逻辑基于每个数据帧具有唯一的
carid

您的ID是按顺序排列的,因此使用
max
carid
生成数字最有意义。如果您有CARID列表,这可能会生成非序列号
[1,2,3200]

这将为雪铁龙生成一个新的
Carid
201
,因为
200
的ID已经存在,并且由一家汽车制造商拥有

作用 行动中 测试额外的数据帧。
new_df=pd.DataFrame({'Carid':[1,2,3],
“卡纳姆”:[梅赛德斯-奔驰”,“丰田”,“宝马])
新建密钥=生成新密钥(df、df2、新密钥df)
{‘雪铁龙’:6,‘丰田’:7}
df3=pd.concat([df1,df2,新的_-df])
df3['Carid']=np.where(df3['Carname'].isin(new_keys.keys()),
df3['Carname'].map(新的_键),df3['Carid'])
打印(df3)
Carid-Carname模型
0 1.0梅赛德斯-奔驰S-Klasse AMG 63s
1.2.0奥迪S6
2 3.0宝马X6 M-Power
0.4.0大众GTI
1 6.0雪铁龙S#<新id
2.5.0欧宝Corsa
0 1.0梅赛德斯-奔驰NaN
1 7.0丰田NaN#<新id
2 3.0宝马南

这是我的目标。请注意,如果可以用新的i=unique id替换df和df2中的Carid,则会容易得多。但继续回答这个问题,我们开始吧

首先,我们为第一个df创建carname和carid之间的映射
cm

d = {'Carid': [1, 2, 3, 1], 'Carname': ['Mercedes-Benz', 'Audi', 'BMW', 'Mercedes-Benz'], 'model': ['S-Klasse AMG 63s', 'S6', 'X6 M-Power', 'Maybach']}
df = pd.DataFrame(data=d)
display(df.head())
cm = {name : id for name, id in zip(df['Carname'], df['Carid'])}
cm
然后,我们对第二个df执行相同的操作

d2 = {'Carid': [4, 1, 5], 'Carname': ['VW', 'Citroen', 'Opel'], 'model': ['GTI', 'S', 'Corsa']}
df2 = pd.DataFrame(data=d2)
display(df2.head())
cm2= {name : id for name, id in zip(df2['Carname'], df2['Carid'])}
cm2

然后,主要的动作是,组合两个映射,保留原始ID,除非发生冲突,在这种情况下,我们分配唯一ID

unique_id = max(list(cm.values()) + list(cm2.values()))+1
for new_name in df2['Carname']:
    if new_name in cm:
        # already included
        pass
    elif cm2[new_name] not in cm.values():
        # unique carid
        cm[new_name] = cm2[new_name]
    else:
        # the new_name is not in cm but its id is

        cm[new_name] = unique_id
        unique_id += 1

print(cm)

现在,cm每个肉身都有唯一的id,保留最初使用的id,除非它们发生冲突:

{'Mercedes-Benz': 1, 'Audi': 2, 'BMW': 3, 'VW': 4, 'Citroen': 6, 'Opel': 5}
现在重新映射ID

df['Carid'] = df['Carname'].replace(cm)
df2['Carid'] = df2['Carname'].replace(cm)
最后将它们结合在一起

dfs = []
dfs.append(df)
dfs.append(df2)
pd.concat(dfs)
结果是

|    |   Carid | Carname       | model            |
|---:|--------:|:--------------|:-----------------|
|  0 |       1 | Mercedes-Benz | S-Klasse AMG 63s |
|  1 |       2 | Audi          | S6               |
|  2 |       3 | BMW           | X6 M-Power       |
|  3 |       1 | Mercedes-Benz | Maybach          |
|  0 |       4 | VW            | GTI              |
|  1 |       6 | Citroen       | S                |
|  2 |       5 | Opel          | Corsa            |

您的第二个df不同于screenshot@Erfan非常感谢你!我把它修好了这个值是如何变为6的?为什么?@MhDG7因为我想要unqiue值。每个龋齿只能发生一次。因为卡里德已经被梅赛德斯-奔驰占领了。雪铁龙也可以有一个Carid
1.1
或一些独特的东西。非常感谢您的帮助!:)非常感谢您的帮助!:)非常感谢你的帮助!这是一个很好的解决方案。@AdrianaSaborowski请参阅纯熊猫编辑方法。
unique_id = max(list(cm.values()) + list(cm2.values()))+1
for new_name in df2['Carname']:
    if new_name in cm:
        # already included
        pass
    elif cm2[new_name] not in cm.values():
        # unique carid
        cm[new_name] = cm2[new_name]
    else:
        # the new_name is not in cm but its id is

        cm[new_name] = unique_id
        unique_id += 1

print(cm)

{'Mercedes-Benz': 1, 'Audi': 2, 'BMW': 3, 'VW': 4, 'Citroen': 6, 'Opel': 5}
df['Carid'] = df['Carname'].replace(cm)
df2['Carid'] = df2['Carname'].replace(cm)
dfs = []
dfs.append(df)
dfs.append(df2)
pd.concat(dfs)
|    |   Carid | Carname       | model            |
|---:|--------:|:--------------|:-----------------|
|  0 |       1 | Mercedes-Benz | S-Klasse AMG 63s |
|  1 |       2 | Audi          | S6               |
|  2 |       3 | BMW           | X6 M-Power       |
|  3 |       1 | Mercedes-Benz | Maybach          |
|  0 |       4 | VW            | GTI              |
|  1 |       6 | Citroen       | S                |
|  2 |       5 | Opel          | Corsa            |