pandas 比较两个不同大小的数据帧映射值,并在缺失值时添加任意值

Posted

技术标签:

【中文标题】pandas 比较两个不同大小的数据帧映射值,并在缺失值时添加任意值【英文标题】:pandas compare two different size dataframe mapping values and adding an arbitrary value when ones is missing 【发布时间】:2020-12-05 01:29:51 【问题描述】:

尝试学习 pandas,并将其应用于我正在使用标准 python/php 工具使用各种循环解决的问题。

假设我有两个这样的数据帧,df1 小于 df2,对于 df2 中的 ClientApplication 值,df1 中可能没有相应的子程序

df1

ClientApplication Subprogram
insert_data       AA1
remove_data       AB1
update_data       XX0

df2

Time       ClientApplication Duration Result
2020-01-01 insert_data       300      error
2020-02-01 insert_data       100      ok
2020-03-01 update_data       1000     ok
2020-06-02 remove_data       50       error
2020-07-01 check_data        0        ok

我需要完成几件事:

在 df2 中为 Subprogram 添加一列,其值对应 到 df1 中的同一个 ClientApplication。当没有一个 在 df1 中找到的对应添加一个任意值('Unknown')

使用子程序在 df1 中添加缺少的 ClienApplication 值 值设置为“未知”的任意值

我可以使用 on 条件通过合并获得我想要的,我知道我也可以使用地图来实现这一点,但是我找不到通过添加任意字符串“未知”来管理缺失值的方法除了基于 NaN 值进行其他操作之外,在这种情况下,我看不到在 pandas 中实现这一目标的最紧凑和最有效的方法。

df1 是一个小于 1000 行的小型数据框,而 df2 将是数百万行。

df1 是从 SQL 查询构造的,而 df2 是从 csv 构造的,df1 表将需要更新,因为 csv 包含所有新识别的 Unknown ClientApplication 并且 df2 将被导入带有添加列的 db和更新的值,这与任务无关,但可能会影响选择最有效的方法?

【问题讨论】:

如果有任何问题帮助或解决了问题,请考虑accepting it :-) 对不起,我一直没有解决这个问题,我在业余时间做。我尝试了一些解决方案,但没有一个完全符合我的要求,但他们指出了实现我需要的正确方法,我会尽快回复大家并发布一个可行的解决方案 【参考方案1】:

如果我理解正确,首先让我们创建数据框:

from io import StringIO
content = """ClientApplication Subprogram
insert_data AA1
remove_data AB1
update_data XX0
"""
df1 = pd.read_csv(StringIO(content), sep=" ")
print(df1)
  ClientApplication Subprogram
0       insert_data        AA1
1       remove_data        AB1
2       update_data        XX0
content = """Time ClientApplication Duration Result
2020-01-01 insert_data 300 error
2020-02-01 insert_data 100 ok
2020-03-01 update_data 1000 ok
2020-06-02 remove_data 50 error
2020-07-01 check_data 0 ok
"""
df2 = pd.read_csv(StringIO(content), sep=" ")
print(df2)
         Time ClientApplication  Duration Result
0  2020-01-01       insert_data       300  error
1  2020-02-01       insert_data       100     ok
2  2020-03-01       update_data      1000     ok
3  2020-06-02       remove_data        50  error
4  2020-07-01        check_data         0     ok

好的,现在合并:

result = pd.merge(df1, df2, how='right', on='ClientApplication', )
result
ClientApplication   Subprogram  Time    Duration    Result
0   insert_data AA1 2020-01-01  300 error
1   insert_data AA1 2020-02-01  100 ok
2   remove_data AB1 2020-06-02  50  error
3   update_data XX0 2020-03-01  1000    ok
4   check_data  NaN 2020-07-01  0   ok

现在您可以使用 .fillna() 来“设置为 'Unknown' 的任意值”

result.fillna("Unknown")
ClientApplication   Subprogram  Time    Duration    Result
0   insert_data AA1 2020-01-01  300 error
1   insert_data AA1 2020-02-01  100 ok
2   remove_data AB1 2020-06-02  50  error
3   update_data XX0 2020-03-01  1000    ok
4   check_data  Unknown 2020-07-01  0   ok

【讨论】:

【参考方案2】:

要在 df2 中创建新列,请使用 mapfillna

s = df1.set_index('ClientApplication')['Subprogram']
df2['Subprogram'] = df2['ClientApplication'].map(s).fillna('Unknown')

#result df2
    Time        ClientApplication   Duration    Result  Subprogram
0   2020-01-01  insert_data         300         error   AA1
1   2020-02-01  insert_data         100         ok      AA1
2   2020-03-01  update_data         1000        ok      XX0
3   2020-06-02  remove_data         50          error   AB1
4   2020-07-01  check_data          0           ok      Unknown

我发现在 df1 中添加新值的最简单方法是在 df2 中使用 drop_duplicates 重做 df1(我相信这比 merge 更快,也许你可以测试证明?!:-))

df1 = df2[['ClientApplication', 'Subprogram']].drop_duplicates()

#result df1
    ClientApplication   Subprogram
0   insert_data         AA1
2   update_data         XX0
3   remove_data         AB1
4   check_data          Unknown

【讨论】:

以上是关于pandas 比较两个不同大小的数据帧映射值,并在缺失值时添加任意值的主要内容,如果未能解决你的问题,请参考以下文章

根据 pandas df 中的多个条件映射不同的数据帧

Pandas 映射 2 个数据帧中的值和外连接 + 聚合值

合并两个不同长度的python pandas数据帧,但将所有行保留在输出数据帧中

检查panda数据帧中的多个列是否重合并在新列中标记它们

将多个键上的 pandas 数据帧映射为列或 multiIndex

如何使用 Python Pandas 比较两个不同大小的数据集?