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



我正在尝试学习panda,并将其应用于我使用标准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中找到的对应项添加任意值("未知"(

  • 用子程序添加df1中缺少的ClienApplication值值设置为"未知"的任意值

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

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

df1是从SQL查询构建的,而df2是从csv构建的,当csv包含所有新标识的未知客户端应用程序时,需要更新df1表,并且df2将导入到数据库中,并添加列和更新值,这与任务无关,但可能会影响选择最有效的方式?

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

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((来";设置为"未知"的任意值;

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

要在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

最新更新