加入字符串时,Pandas 合并结果缺少行

Posted

技术标签:

【中文标题】加入字符串时,Pandas 合并结果缺少行【英文标题】:Pandas merge result missing rows when joining on strings 【发布时间】:2018-10-19 22:49:02 【问题描述】:

我有一个一直在清理的数据集,为了清理它,我需要将其放入数据透视表中以汇总一些数据。我现在将它放回数据框,以便我可以将它与其他一些数据框合并。 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 个 MKTcodes 的列表并在它与我指定的每个区域匹配的地方执行合并?像一对多匹配?

谢谢。

【问题讨论】:

【参考方案1】:

当合并没有按预期工作时,首先要做的是查看有问题的列。

在大多数情况下,最大的罪魁祸首是尾随/前导空格。这些通常是在从文件中错误读取 DataFrame 时引入的。

尝试通过去除多余的空白字符来消除它们。假设您需要加入“区域”列,请使用

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+', ' ')

【讨论】:

你是 100% 正确的!一旦允许我也将您的答案标记为正确。我将来必须注意这一点。谢谢! 你也可以(可能)做一些通用的事情,比如:df1.select_dtypes(object).applymap(str.strip).ne(df1.select_dtypes(object)) 来获取这些项目的掩码 @JonClements 整洁,谢谢!顺便问一下,知道select_dtypes 是返回视图还是数据的新副本? 我很抱歉,但面具是什么? @CharlesD 这是一个布尔值的数据框,你可以用它来索引df,以及类似的东西(事后调试)。

以上是关于加入字符串时,Pandas 合并结果缺少行的主要内容,如果未能解决你的问题,请参考以下文章

pandas,如果行包含通配符文本,则合并重复项

Pandas分组时字符串列合并的方法

pandas中列方向字符统计及其合并

pandas中列方向字符统计及其合并

熊猫内部合并/加入返回所有行

与 pandas 的近似连接