Pandas合并结果在字符串连接时缺失行

3

我有一个数据集,希望进行清洗。为了清洗它,我需要将其转化成透视表以便对部分数据进行汇总。现在我正在将其转回到数据框中,以便与其他数据框合并。df1 的样子如下:

    Count   Region              Period      ACV  PRJ
    167     REMAINING US WEST   3/3/2018    5    57
    168     REMAINING US WEST   3/31/2018   10   83
    169     SAN FRANCISCO       1/13/2018   99   76
    170     SAN FRANCISCO       1/20/2018   34   21

df2看起来像这样:

Count  MKTcode  Region
11     RSMR0    REMAINING US SOUTH
12     RWMR0    REMAINING US WEST
13     SFR00    SAN FRANCISCO

我已经尝试使用以下代码将它们合并:

df3 = pd.merge(df1, df2, on='Region', how='inner')

但出于某种原因,Pandas 没有将“Region”列解释为相同数据,合并的结果在“MKTcode”列中出现 NaN 数据,而且似乎是将 df2 添加到 df1 上,如下所示:

Count  Region             Period    ACV             PRJ         MKTcode
193 WASHINGTON, D.C.    3/3/2018    36               38             NaN
194 WASHINGTON, D.C.    3/31/2018   12                3             NaN
195 ATLANTA              NaN        NaN             NaN           ATMR0
196 BOSTON               NaN        NaN             NaN           B2MRN

我尝试使用内连接和外连接,但实际问题似乎是pandas将每个数据帧的Region列解释为不同的元素。df2中的MKTcode列和Region列仅有12个观测值,并且每个观测值只出现一次,而df1的Region列具有多个重复的实例(同一城市的多个倍数)。是否有一种方法可以创建一个包含我需要的12个MKT代码的列表,并执行匹配我指定的每个区域的合并?像一对多的匹配吗?
谢谢。
1个回答

8

当合并操作不如预期时,首先要做的是查看有问题的列。

在大多数情况下,最主要的原因是尾随/前导空格。这通常是由于错误地从文件中读取DataFrames而引入的。

尝试通过去除空格字符来消除额外的空格。假设您需要在“Region”列上进行连接,请使用以下方法:

for df in (df1, df2):
    # Strip the column(s) you're planning to join with
    df['Region'] = df['Region'].str.strip()

现在,合并应该按预期工作。
pd.merge(df1, df2, on='Region', how='inner')

   Count_x             Region     Period  ACV  PRJ  Count_y MKTcode
0      167  REMAINING US WEST   3/3/2018    5   57       12   RWMR0
1      168  REMAINING US WEST  3/31/2018   10   83       12   RWMR0
2      169      SAN FRANCISCO  1/13/2018   99   76       13   SFR00
3      170      SAN FRANCISCO  1/20/2018   34   21       13   SFR00

如果您仍然遇到NaN问题,可能是因为单词之间的空格字符不同。例如, 'REMAINING US WEST'将无法与'REMAINING US WEST'相等。

这个问题可以通过使用str.replace来解决:

for df in (df1, df2):
    df['Region'] = df['Region'].str.replace(r'\s+', ' ')

1
你是100%正确的!一旦允许我标记您的答案为正确,我就会这样做。将来我会留意这个。谢谢! - CharlesD
2
你也可以(可能)做一些通用的操作,例如:df1.select_dtypes(object).applymap(str.strip).ne(df1.select_dtypes(object)),以获取这些项的掩码。 - Jon Clements
@JonClements 很好,谢谢!顺便问一下,您知道 select_dtypes 返回的是视图还是数据的新副本吗? - cs95
抱歉,什么是掩码? - CharlesD
@CharlesD 这是一个布尔值数据帧,您可以使用它来索引到 df,以及类似的东西(事后调试)。 - cs95
@cᴏʟᴅsᴘᴇᴇᴅ 我认为这是一份副本 :( (如果 df1.select_dtypes(object)._is_view 是什么意思...我确定那不是正确的方法...大脑疲惫 :) (我认为应该是 values.base is... other.values.base 或类似的东西 - Jon Clements

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接