我正在尝试学习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中创建新列,请将map
与fillna
一起使用
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