使用df.merge在df中填充新列会产生奇怪的匹配

时间:2017-08-17 14:04:30

标签: python pandas dataframe merge

我刚刚发现导致此问题的2个问题,请参阅下面的解决方案

我想基于另一个数据帧在我的数据框(df)中创建一个新列。 基本上df2包含我想插入df的更新信息。 为了复制我的真实案例(> 1m行),我将用简单列填充两个随机df。

我使用pandas.merge()来做到这一点,但这给了我奇怪的结果。

这是一个典型的例子。让我们随机创建df并用简单的关系创建df2:“New Type”=“Type”+ 1.我创建这个简单的关系,以便我们可以轻松检查输出。在我的实际应用中,我当然没有这么简单的关系。

import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(0,100,size=(100, 1)),columns = ["Type"])
df.head()

   Type
0    45
1     3
2    89
3     6
4    39

df1 = pd.DataFrame({"Type":range(1,100)})
df1["New Type"] = df1["Type"] + 1
print(df1.head())

 Type  New Type
0     1         2
1     2         3
2     3         4
3     4         5
4     5         6

现在假设我想根据df1上的“新类型”更新df“Type”

df["Type2"] = df.merge(df1,on="Type")["New Type"]
print(df.head())

我得到这个奇怪的输出,我们清楚地看到它不起作用

  Type  Type2
0    45   46.0
1     3    4.0
2    89    4.0
3     6    4.0
4    39   90.0

我认为输出应该像

  Type  Type2
0    45   46.0
1     3    4.0
2    89   90.0
3     6    7.0
4    39   40.0

只有第一行才能正确匹配。你知道我错过了什么吗?

解决方案

1.我需要与how =“left”合并,否则默认选择是“inner”,生成另一个尺寸不同于df的表。

  1. 另外,我需要使用sort = false作为我的合并函数的属性。否则,合并结果将在应用于df。
  2. 之前进行排序

2 个答案:

答案 0 :(得分:1)

使用mapset_indexsqueeze执行此操作的一种方法:

df['Type2'] = df['Type'].map(df1.set_index('Type').squeeze())

输出:

   Type  Type2
0    22   23.0
1    56   57.0
2    63   64.0
3    33   34.0
4    25   26.0

答案 1 :(得分:0)

首先,我构建了一系列由New Type Type的旧df1索引的new_vals = df1.set_index('Type')['New Type']

df.replace(new_vals)

然后它只是:

NaN

这将保留未完整映射的值。如果您希望输出为new_vals[df.Type] (null)而未映射,请执行以下操作:

search